MySQL - GROUP_CONCAT()与连接表 - 意外结果

时间:2013-01-28 06:35:34

标签: mysql sql join

我有两张桌子 - 一张用于描述您可以购买的商品,另一张用于存储购买其他商品所需的商品。第一个表中有一些项目需要其他项目作为交易形式。有时您需要一定数量的所需物品。这是两个表的模式:

+---------------+-----------------+------+-----+---------+----------------+
| Field         | Type            | Null | Key | Default | Extra          |
+---------------+-----------------+------+-----+---------+----------------+
| storeID       | int(5) unsigned | NO   | PRI | NULL    | auto_increment |
| itemID        | int(10)         | NO   |     | NULL    |                |
| quantity      | int(10)         | NO   |     | NULL    |                |
| cost          | int(10)         | NO   |     | NULL    |                |
+---------------+-----------------+------+-----+---------+----------------+

+----------+---------+------+-----+---------+-------+
| Field    | Type    | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| parentID | int(10) | NO   |     | NULL    |       |
| itemID   | int(10) | NO   |     | NULL    |       |
| quantity | int(10) | NO   |     | NULL    |       |
+----------+---------+------+-----+---------+-------+

第二个表与第一个表storeID <-> parentID相关联。商店中的商品可能包含许多必需品。

问题: 我需要运行一个返回商店中所有商品的查询,但是还显示所有必需的商品及其数量。看起来应该是这样的:

4 x Item1,5 x Item2

我有这个当前的查询:

SELECT a.*, b.typeName, GROUP_CONCAT(CONCAT(c.quantity, " x ", d.typeName)) as `reqItems`
        FROM lpStore a 
        INNER JOIN typeNames b ON (a.typeID = b.typeID)
        INNER JOIN lpRequiredItems c ON (a.storeID = c.parentID)
        INNER JOIN typeNames ON (d.typeID = c.typeID)
        GROUP BY c.parentID
        ORDER BY a.cost ASC 

typeNames只是一个将itemID与其实际名称相关联的表。

现在,此查询效果很好,但似乎不包含没有必要的项目的项目。我怀疑它是JOINS中的一个,以及GROUP BY(它可能正在对该表中不存在的所有NULL值进行分组?),但是我还没有弄清楚它。如果不需要,我需要它在该列中返回空白或NULL。

编辑:样本数据

为了简单起见,我删除了使用项目名称表加入表格

此处提供的示例数据:http://www.sqlfiddle.com/#!2/d8dca/1

实际结果:

+---------+--------+------+----------+-----------------------------+
| storeID | typeID | cost | quantity | reqItems                    |
+---------+--------+------+----------+-----------------------------+
|       1 |   2514 | 2000 |        3 | 5 x 3668,10 x 4825          |
|       3 |   8785 | 5000 |        2 | 1 x 4875,15 x 1102,5 x 9813 |
|       4 |    579 | 1500 |        5 | NULL                        |
+---------+--------+------+----------+-----------------------------+

预期结果:

+---------+--------+------+----------+-----------------------------+
| storeID | typeID | cost | quantity | reqItems                    |
+---------+--------+------+----------+-----------------------------+
|       1 |   2514 | 2000 |        3 | 5 x 3668,10 x 4825          |
|       2 |   3199 | 1000 |        1 | NULL                        |
|       3 |   8785 | 5000 |        2 | 1 x 4875,15 x 1102,5 x 9813 |
|       4 |    579 | 1500 |        5 | NULL                        |
+---------+--------+------+----------+-----------------------------+

3 个答案:

答案 0 :(得分:4)

问题是GROUP BY parentId,将GROUP_CONCAT()放在子查询中,然后在子查询上使用LEFT JOIN。当GROUP BY parentId等于null时,这些值将被忽略,因此您不会返回任何结果:

SELECT  a.`storeID`, 
        a.`typeID`, 
        a.`cost`, 
        a.`quantity` , 
        `reqItems` 
FROM    lpStore a
LEFT JOIN
(
  select  parentID,
     GROUP_CONCAT( CONCAT( quantity,  " x ", typeID ) ) AS  `reqItems` 
  from lpRequiredItems
  group by parentID
) c 
  ON ( a.storeID = c.parentID ) 
ORDER   BY  a.`storeID`, 
        a.`typeID`, 
        a.`cost`, 
        a.`quantity`
LIMIT 0 , 30

请参阅SQL Fiddle with Demo

结果是:

| STOREID | TYPEID | COST | QUANTITY |                    REQITEMS |
--------------------------------------------------------------------
|       1 |   2514 | 2000 |        3 |          5 x 3668,10 x 4825 |
|       2 |   3199 | 1000 |        1 |                      (null) |
|       3 |   8785 | 5000 |        2 | 5 x 9813,1 x 4875,15 x 1102 |
|       4 |    579 | 1500 |        5 |                      (null) |

答案 1 :(得分:0)

问题是“内部联接”,它只返回具有匹配项的值,即“必需”表中的条目。请尝试左连接。

SELECT a.*, b.typeName, GROUP_CONCAT(CONCAT(c.quantity, " x ", d.typeName)) as `reqItems`
        FROM lpStore a 
        INNER JOIN typeNames b ON (a.typeID = b.typeID)
        LEFT JOIN lpRequiredItems c ON (a.storeID = c.parentID)
        INNER JOIN typeNames ON (d.typeID = c.typeID)
        GROUP BY c.parentID
        ORDER BY a.cost ASC 

答案 2 :(得分:0)

您只需使用LEFT JOIN代替INNER JOIN

SELECT  a.`storeID`, 
        a.`typeID`, 
        a.`cost`, 
        a.`quantity` , 
        GROUP_CONCAT( CONCAT( c.quantity,  " x ", c.typeID ) ) AS  `reqItems` 
FROM    lpStore a
        LEFT JOIN lpRequiredItems c 
            ON ( a.storeID = c.parentID ) 
GROUP   BY c.parentID
ORDER   BY  a.`storeID`, 
        a.`typeID`, 
        a.`cost`, 
        a.`quantity` 
LIMIT 0 , 30