SQL查询以查找数量为1的唯一订单

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

我有一个名为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和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。多谢多谢!