我有很多表并执行大查询(约5-7 LEFT JOIN)。 看起来像这样
SELECT *, t.id
GROUP_CONCAT(field SEPARATOR '|') AS fields,
GROUP_CONCAT(other SEPARATOR '|') AS others
FROM table t
LEFT JOIN tablefields tf ON t.id = tf.user_id
LEFT JOIN tableothers to ON t.id = to.user_id
GROUP BY t.id
这是问题所在。所有字段都很好,但是两个就像'value | value | value | value'(15-17次),即使连接表中只有一行。
我做错了什么?
P.S。
我不能使用DISTINCT,因为一个字段是section_id而其他字段是note。注意可能类似,但section_id是唯一的。
P.P.S
https://gist.github.com/3098105
查看查询结果的一部分。
mysql> SELECT * FROM tablename;
+----+---------+------------+-----------+
| id | user_id | section_id | note_data |
+----+---------+------------+-----------+
| 1 | 1331 | UserVideo | test |
| 2 | 1331 | UserNCAA | test |
+----+---------+------------+-----------+
2 rows in set (0.00 sec)
答案 0 :(得分:5)
如果tablefields
和tableothers
中有多个匹配的行,则会获得行的交叉积。 (我相信马库斯亚当斯在评论中得到的结论。)
如果您想要每个表中的“列表”,而不生成任何“重复”,请尝试以下方法:
SELECT tt.id
, tt.fields
, GROUP_CONCAT(to.other ORDER BY to.other SEPARATOR '|') AS `others`
FROM (SELECT t.id
, GROUP_CONCAT(tf.field ORDER BY tf.field SEPARATOR '|') AS `fields`
FROM table t
LEFT JOIN tablefields `tf` ON t.id = tf.user_id
GROUP BY t.id
) tt
LEFT JOIN tableothers `to` ON tt.id = to.user_id
GROUP BY tt.id, tt.fields
这个内嵌视图别名为tt
,可以从tablefields
获取每个t.id
的单行列表。然后可以将该结果集连接到tableothers
表,以从该表中获取列表。以这种方式生成结果集可以避免在每个表中存在多个匹配行时生成额外的重复项,否则会产生交叉产品。
您注意到您无法使用DISTINCT
关键字,因为您希望保留每个列表中的重复值。如果这不是必需的,如果您可以允许消除重复值,那么您使用DISTINCT
关键字来获得几乎相同的结果:
SELECT t.id
, GROUP_CONCAT(DISTINCT tf.field ORDER BY tf.field SEPARATOR '|') AS `fields`
, GROUP_CONCAT(DISTINCT to.other ORDER BY to.other SEPARATOR '|') AS `others`
FROM table t
LEFT JOIN tablefields `tf` ON t.id = tf.user_id
LEFT JOIN tableothers `to` ON t.id = to.user_id
GROUP BY t.id
此方法允许生成交叉产品,但随后会消除所有重复项,即“交叉产品”操作生成的重复值,以及本机数据中存在的重复项。
答案 1 :(得分:-2)
这是因为t。*。您应该只选择要应用分组的列。像
这样的东西SELECT t.id,
GROUP_CONCAT(field SEPARATOR '|') AS fields,
GROUP_CONCAT(other SEPARATOR '|') AS others
FROM table t
LEFT JOIN tablefields tf ON t.id = tf.user_id
LEFT JOIN tableothers to ON t.id = to.user_id
GROUP BY t1.id