【问题标题】:SQL query to find unique Orders with a Quantity of 1SQL查询以查找数量为1的唯一订单
【发布时间】:2015-06-02 05:21:25
【问题描述】:

我有一个名为 OrderItems 的表。我想编写一个查询,返回数量 = 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 的订单,并且其中的数量必须为一个。

【问题讨论】:

  • 查询具有“oi.OrderId = o.Id”,但示例显示具有不同 Id 与 OrderId 的行
  • Id 只是 Identity 列,与 o.Id 列根本无关。对不起,如果这令人困惑。我只是想表明每一行都是独一无二的。

标签: sql sql-server


【解决方案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

【讨论】:

  • 您的查询将返回 ID = 3 的订单 ID 125,根据 OP,这不是所需的结果。
  • 我刚刚使用 Order 表观察到 OP。考虑到这一点,要获得所需的输出,您不需要加入 Orders 表,您仍然可以仅使用 OrderItems 表获得相同的结果。有问题的 OrderItems 表中的 Id 列看起来像一个代理键。
  • 只是想知道你为什么使用 Count(*)。总和应该给出相同的结果。是用来处理负值情况的吗?
  • 是的,我添加了 count(*) 以消除负数和零记录,以防万一这些记录存在
  • 好点:)。您可以在答案中编辑我的小提琴。我使用了与 OP 要求相同的数据。这将有助于改善答案。不幸的是我没有创建订单表:)
【解决方案2】:

您没有指定您的 SQL Server 版本,但使用组计数将消除重新加入 OrderItems 的需要:

select * 
from
 (
   select *, 
      count(*) over (partition by orderId) as cnt
   from OrderItems
 ) dt 
where cnt = 1 and Qty = 1

Fiddle

这是否更有效取决于实际数据...

【讨论】:

  • SQL 2014。非常感谢!
【解决方案3】:

为每个订单添加您的订单数量,如果是一个,那就是您需要的。 要选择任何列,您可以再次加入您的 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

SQL Fiddle

【讨论】:

    【解决方案4】:

    一个简单的方法是使用窗口函数:

    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;
    

    这两者的关键是joinOrders 是不必要的。

    【讨论】:

      【解决方案5】:

      您可以使用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)
      

      【讨论】:

        【解决方案6】:

        性能方面:

        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 
        

        【讨论】:

          猜你喜欢
          • 2023-03-11
          • 1970-01-01
          • 2019-03-06
          • 1970-01-01
          • 1970-01-01
          • 2016-12-29
          • 1970-01-01
          • 2015-01-22
          • 2019-12-11
          相关资源
          最近更新 更多