【问题标题】:MySQL 'group by' with 'left join' throws away some entriesMySQL 'group by' 和 'left join' 丢弃了一些条目
【发布时间】:2014-10-14 16:36:54
【问题描述】:

我有一个看起来像这样的查询:

SELECT 
    orders.order_id,
    items.item_id, 
    GROUP_CONCAT(graphics.graphic_id) AS graphic_ids
FROM orders orders 
    LEFT JOIN order_items items ON orders.order_id = items.order_id 
    LEFT JOIN order_graphics graphics on graphics.item_id = items.item_id
WHERE // etc
GROUP BY items.item_id

订单可以有零个或多个项目,项目可以有零个或多个图形。目标是获取所有符合 WHERE 条件的订单,按订单商品逐项列出,并在每个订单商品上列出图形,如下所示:

// ideal
+----------+---------+---------------+    
| order_id | item_id | graphic_ids   |
+----------+---------+---------------+
|     3097 |  NULL   | NULL          |
|     3098 |  NULL   | NULL          |
|     3099 |  NULL   | NULL          |
|     3100 |  112437 | NULL          |
|     3101 |  112677 | 127003        |
|     3102 |  112948 | 127314        |
|     3102 |  112949 | 127315        |
|     3102 |  112950 | 127316        |
|     3103 |  122807 | 138005,138006 |
+----------+---------+---------------+

但是,GROUP BY / GROUP_CONCAT 子句意味着所有零项目的订单都被分组在 NULL 下:

// reality
+----------+---------+---------------+
|     3097 |  NULL   | NULL          |
|     3100 |  112437 | NULL          |
|     3101 |  112677 | 127003        |
|     3102 |  112948 | 127314        |
|     3102 |  112949 | 127315        |
|     3102 |  112950 | 127316        |
|     3103 |  122807 | 138005,138006 |
+----------+---------+---------------+

有没有什么好的方法可以group by`item_id 同时列出所有没有商品的订单?

【问题讨论】:

  • 如果您在GROUP BY 中包含两列,您应该得到正确的结果,不是吗? GROUP BY orders.order_id, items.item_id。 MySQL 的默认行为(与大多数其他 RDBMS 不同)是允许 SELECT 中的列而不是 GROUP BY 中的列,有时结果不确定或令人困惑。
  • 不错!我不知道可以有两个 GROUP BY。我想这很有意义。谢谢!
  • 理想情况下,出现在 SELECT 中或在计算中使用但不属于聚合的 所有 列(COUNT(),SUM(),MAX(),GROUP_CONCAT() 等...)属于 @987654330 @ 以获得可预测的结果。但有时很难实现。
  • 有趣。如果查询选择了几十列,这听起来有点矫枉过正,但我​​会记住这一点。
  • 这与聚合函数的应用方式有关。如果所有列都没有在GROUP BY 中分组,MySQL 必须猜测你想要的未分组列的值。通常它会选择与组匹配的 first 值,这可能是您想要的,并且在对具有许多相似行的单个表进行分组时通常很好,但在处理连接时会导致问题。

标签: mysql group-by left-join


【解决方案1】:

您应该在 group by 子句中包含不是聚合计算的每一列:

SELECT 
    orders.order_id,
    items.item_id, 
    GROUP_CONCAT(graphics.graphic_id) AS graphic_ids
FROM orders orders 
    LEFT JOIN order_items items ON orders.order_id = items.order_id 
    LEFT JOIN order_graphics graphics on graphics.item_id = items.item_id
WHERE // etc
GROUP BY orders.order_id, items.item_id

【讨论】:

    猜你喜欢
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 2021-01-30
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    相关资源
    最近更新 更多