Mir*_*age 1 mysql group-concat
我有很多表并执行大查询(大约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
Run Code Online (Sandbox Code Playgroud)
这是问题所在.所有字段都很好,但是两个就像'value | value | value | value'(15-17次),即使连接表中只有一行.
我做错了什么?
PS
我不能使用DISTINCT,因为一个字段是section_id而其他字段是note.注意可能类似,但section_id是唯一的.
PPS
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)
Run Code Online (Sandbox Code Playgroud)
当你同时在多个匹配的行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
Run Code Online (Sandbox Code Playgroud)
这个内联视图别名为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
Run Code Online (Sandbox Code Playgroud)
此方法允许生成交叉产品,但随后消除所有重复项,即"交叉产品"操作生成的重复值,以及本机数据中存在的重复值.