使用LEFT JOIN对相同的行进行分类,而不重复一对多关系

时间:2012-08-05 07:07:23

标签: mysql join one-to-many group-concat

请原谅我的问题标题,我不知道该怎么说,我有以下两个表格。

products                orders
+------+----------+     +--------+------+-------+
|  id  | name     |     |   id   |  qty |  pid  |
+------+----------+     +--------+------+-------+
|  1   | mouse    |     | 10001  |  20  |   1   |
|  2   | keyboard |     | 10002  |  15  |   3   |
|  3   | headset  |     | 10004  |  5   |   3   |
+------+----------+     | 10005  |  12  |   2   | 
                        | 10006  |  18  |   1   |
                        +--------+------+-------+

这是我正在使用的LEFT JOIN查询和输出

SELECT p.id AS No, p.name AS ProductName, o.qty AS Quantity
FROM products AS p
LEFT JOIN orders AS o ON p.id = o.pid

+------+-------------+----------+
|  No  | ProductName | Quantity |
+------+-------------+----------+
|  1   | mouse       |   20     |
|  1   | mouse       |   18     |
|  2   | keyboard    |   12     | 
|  3   | headset     |   15     |
|  3   | headset     |    5     |
+------+-------------+----------+

我想要实现的是如下输出:

+------+-------------+----------+
|  No  | ProductName | Quantity |
+------+-------------+----------+
|  1   | mouse       |   20     |
|      |             |   18     |
|  2   | keyboard    |   12     | 
|  3   | headset     |   15     |
|      |             |    5     |
+------+-------------+----------+

我的问题是可以这样做吗?任何回复和建议都非常感谢。感谢。

P / S:我也尝试过使用GROUP_CONCAT(qty SEPARATOR“,”),但它会将结果返回到一行,因为将来我可能会在Orders表中添加更多的其他列,这将很难阅读。

2 个答案:

答案 0 :(得分:2)

当然,这是可能的 - 而且无需使用变量:

SELECT    IF(c.min_oid IS NOT NULL, a.id,   NULL) AS No,
          IF(c.min_oid IS NOT NULL, a.name, NULL) AS ProductName,
          b.qty AS Quantity
FROM      products a
JOIN      orders b ON a.id = b.pid
LEFT JOIN (
          SELECT   MIN(id) AS min_oid
          FROM     orders
          GROUP BY pid
          ) c ON b.id = c.min_oid
ORDER BY  a.id,
          b.id

基本上它正在做的是如果行不是特定产品的最小订单ID,则显示空白(NULL),否则显示信息。


SQLFiddle Demo

答案 1 :(得分:1)

在这种情况下,您可以使用MySQL变量。我将以前的产品ID存储在变量@prev中,并且只有在更改时我们才会输出产品名称。

http://www.sqlfiddle.com/#!2/d5fd6/9

SET @prev := NULL;

SELECT
  IF( @prev = p.id, NULL, p.id) AS No,
  IF( @prev = p.id, NULL, p.name) AS ProductName,
  o.qty AS Quantity
 ,@prev := p.id

FROM products AS p

LEFT JOIN orders AS o
       ON p.id = o.pid