SQL查询以查找数量为1的唯一订单
我有一个名为OrderItems的表。我想编写一个查询,返回quantity=1的行,但是如果有任何其他记录具有相同的OrderID,我不希望返回任何内容SQL查询以查找数量为1的唯一订单,sql,sql-server,Sql,Sql Server,我有一个名为OrderItems的表。我想编写一个查询,返回quantity=1的行,但是如果有任何其他记录具有相同的OrderID,我不希望返回任何内容 Id OrderID Qty SKU 1 123 1 abc123 2 124 2 sho221 3 125 1 toy903 4 125 3 ball05 5 155 1 gree32 使用上面的示例数据,我只希望返回订单123和15
Id OrderID Qty SKU
1 123 1 abc123
2 124 2 sho221
3 125 1 toy903
4 125 3 ball05
5 155 1 gree32
使用上面的示例数据,我只希望返回订单123和155,因为它们用于数量为1的单个SKU。订单125有两个SKU,即使第一个Id 3的数量为1,另一个Id 4的数量为3,所以我不希望这些订单被退回
到目前为止,我正在处理的问题是:
SELECT o.Id
FROM Orders o
INNER JOIN OrderItems oi
ON oi.OrderId = o.Id
WHERE oi.Quantity = 1
GROUP BY eo.Id
但此查询不考虑具有多个SKU的订单,只考虑恰好具有数量为1的SKU的订单
用简单的英语-我想查找只包含单个SKU的订单,其中必须有一个数量。您可以使用exists操作符检查相同SKU的其他项目
SELECT *
FROM orders a
WHERE qty = 1 AND
NOT EXISTS (SELECT *
FROM orders b
WHERE a.orderid = b.orderid AND a.id != b.id)
您可以使用exists运算符检查相同SKU的其他项目
SELECT *
FROM orders a
WHERE qty = 1 AND
NOT EXISTS (SELECT *
FROM orders b
WHERE a.orderid = b.orderid AND a.id != b.id)
我认为你也可以通过以下方式做到这一点:
SELECT
oi.OrderId,
sum(oi.Quantity)
FROM
Orders o
INNER JOIN OrderItems oi
ON oi.OrderId = o.Id
group by
oi.OrderId
having
sum(oi.Quantity) = 1 and
count(*) = 1
我认为你也可以通过以下方式做到这一点:
SELECT
oi.OrderId,
sum(oi.Quantity)
FROM
Orders o
INNER JOIN OrderItems oi
ON oi.OrderId = o.Id
group by
oi.OrderId
having
sum(oi.Quantity) = 1 and
count(*) = 1
为每个订单添加您的订单数量。如果是一个订单,那就是您所需要的。 若要选择任何列,则可以再次加入orderItem表
select * from
OrderItems x inner join
(
select orderId, sum(Qty) AS NetQty
from OrderItems
group by orderId
having sum(Qty) =1
) t
on t.orderId = x.orderId
为每个订单添加您的订单数量。如果是一个订单,那就是您所需要的。 若要选择任何列,则可以再次加入orderItem表
select * from
OrderItems x inner join
(
select orderId, sum(Qty) AS NetQty
from OrderItems
group by orderId
having sum(Qty) =1
) t
on t.orderId = x.orderId
关于性能:
SELECT o.Id
FROM Orders o
INNER JOIN OrderItems oi
ON oi.OrderId = o.Id
LEFT JOIN OrderItems oi1
ON oi.OrderId = oi1.OrderId
AND oi.Id <> oi1.Id
WHERE oi.Qty = 1
AND oi1.id IS NULL
关于性能:
SELECT o.Id
FROM Orders o
INNER JOIN OrderItems oi
ON oi.OrderId = o.Id
LEFT JOIN OrderItems oi1
ON oi.OrderId = oi1.OrderId
AND oi.Id <> oi1.Id
WHERE oi.Qty = 1
AND oi1.id IS NULL
您没有指定SQL Server版本,但使用组计数将消除重新连接到OrderItems的需要:
如果这更有效,则取决于实际数据…您没有指定SQL Server版本,但使用组计数将消除重新连接到OrderItems的需要:
如果这更有效,则取决于实际数据…一个简单的方法是使用窗口函数:
select oi.*
from (select oi.*, sum(oi.quantity) over (partition by oi.OrderId) as totqty
from OrderItems oi
) oi
where totqty = 1;
该版本很好,因为您可以轻松获取OrderItems中的所有列。如果您只需要订单id:
select oi.orderid
from OrderItems oi
group by oi.orderid
having sum(oi.quantity) = 1;
这两个方面的关键是不需要加入订单。一个简单的方法是使用窗口函数:
select oi.*
from (select oi.*, sum(oi.quantity) over (partition by oi.OrderId) as totqty
from OrderItems oi
) oi
where totqty = 1;
该版本很好,因为您可以轻松获取OrderItems中的所有列。如果您只需要订单id:
select oi.orderid
from OrderItems oi
group by oi.orderid
having sum(oi.quantity) = 1;
这两个问题的关键是不需要加入订单。您的查询将返回ID=3的订单ID 125,根据OP,这不是期望的结果。我只是使用Order table观察到OP。考虑到这一点,要获得所需的输出,您不需要加入Orders表,您仍然可以仅使用OrderItems表获得相同的结果。OrderItems表中的Id列看起来像一个代理项键。只是想知道为什么在创建时使用Count*。总和应给出相同的结果。它是用来处理负值情况的吗?是的,我添加了count*以消除负值和零记录,以防这些记录存在良好的点:。你可以在回答中修改我的提琴。我使用了和OP要求的相同的数据。这将有助于改进答案。不幸的是,我没有创建订单表:您的查询将返回ID=3的订单ID 125,这不是预期的结果。我只是使用订单表观察到了OP。考虑到这一点,要获得所需的输出,您不需要加入Orders表,您仍然可以仅使用OrderItems表获得相同的结果。OrderItems表中的Id列看起来像一个代理项键。只是想知道为什么在创建时使用Count*。总和应给出相同的结果。它是用来处理负值情况的吗?是的,我添加了count*以消除负值和零记录,以防这些记录存在良好的点:。你可以在回答中修改我的提琴。我使用了和OP要求的相同的数据。这将有助于改进答案。不幸的是,我并没有创建订单表:查询的oi.OrderId=o.Id,但示例显示了Id与OrderId不同的行。Id只是标识列,与o.Id列根本不相关。对不起,这让人困惑。我只是想说明每一行都是唯一的。查询具有oi.OrderId=o.Id,但示例显示了Id与OrderId不同的行。Id只是标识列,与o.Id列根本不相关。对不起,这让人困惑。我只是想证明每一行都是唯一的。SQL 2014。多谢多谢!SQL 2014。多谢多谢!