【问题标题】:SQL query to get products in multiple order statesSQL查询获取多个订单状态的产品
【发布时间】:2020-12-16 20:31:54
【问题描述】:

我们有一个产品、订单、order_items、order_status 架构,如下所示。 订单表状态字段,取值; ORDERED、RECEIVING、RECEIVED 和 CANCELED,如 order_status 表中所定义。

与此数据交互的 UI 确实有一个“产品视图”,其中包含每个产品的行。当用户选择产品时,下方的另一个视图(订单中)列出了所选产品所在的订单。

用户应该能够根据产品订单状态过滤产品视图。特别是,“On Order”按钮应过滤产品视图,以仅显示在 In Orders 视图中有记录且状态为“ORDERED”的产品记录。

以下查询返回多个产品行,源于一个产品存在于多个订单中的事实。

SELECT products.*,        
orders.`id` AS orderID,
orders.`status`    
FROM products 
LEFT JOIN order_items
 ON products.`id` = order_items.`product_id`
JOIN orders
 ON orders.`id` = order_items.`order_id`;

我们希望上述结果集在订单状态上“合并”。也就是说,对于每个不同的订单状态,结果集应该只有一个产品记录。然后我们可以在“状态”字段中过滤产品视图。

下图显示了基于上述结果我们想要的结果集。红色表示它应该成为结果的一部分。

如上图所示;

  • ID 为 18 的产品以相同状态重复 3 次。我们只需要其中的一行。
  • ID 为 19 的产品出现在 3 行中,其中两行具有相同的状态。保留状态相同的两行之一,以及状态 = 1 的行。
  • ID 为 20 的产品重复两次,状态相同,保留一次。

如何实现?

【问题讨论】:

  • 请向我们展示您想要的结果。
  • 使用GROUP BY status 为每个状态获取一行。
  • @Barmar 那只返回 2 行.. 不是我要的。
  • @GMB 添加了想要的结果
  • 您写道“结果集应该只有一个记录每个不同的订单状态。”听起来您实际上的意思是“针对每个特定的产品 ID 和状态”。所以GROUP BY products.id, orders.status

标签: mysql sql join left-join greatest-n-per-group


【解决方案1】:

如果您运行的是 MySQL 8.0,则可以使用row_number() 进行过滤。我猜你想要的逻辑是:

select *
from (
    select 
        p.*,        
        o.id as orderid,
        o.status    ,
        row_number() over(partition by p.id, o.status order by o.id) rn
    from products p
    inner join order_items oi on p.id = oi.product_id
    inner join orders o on o.id = oi.order_id
) t
where rn = 1

我认为在这里混合 inner joinleft join 没有意义。使用两个inner joins(如上面的查询),或者如果您想保留没有任何订单的产品,则使用两个left joins。

【讨论】:

  • 运行这个查询,它确实返回了正确的行。惊人的!刚刚了解连接..
【解决方案2】:

使用GROUP BY 将多行合并为一行。使用MIN(o.id) 获取每个组内定义明确的订单ID。

SELECT p.*, MIN(o.id) AS orderID, o.status
FROM products AS p
JOIN order_items AS oi ON oi.product_id = p.id
JOIN orders AS o ON o.id = oi.order_id
GROUP BY p.id, o.status

在这种情况下使用LEFT JOIN 没有意义。您永远不想按来自LEFT JOIN 表的列进行分组,因为所有不匹配的行都将被分组在一起。如果您要过滤订单状态,您显然只需要订单中的产品。

【讨论】:

  • 我尝试了您的查询,但得到以下错误:'on 子句'中的未知列'o.order_id' 我显然是新手!
  • 抱歉,应该是o.id
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-28
  • 2020-03-31
相关资源
最近更新 更多