【发布时间】: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 值,这可能是您想要的,并且在对具有许多相似行的单个表进行分组时通常很好,但在处理连接时会导致问题。