在 group_concat 中排序

Posted

技术标签:

【中文标题】在 group_concat 中排序【英文标题】:Sorting in group_concat 【发布时间】:2016-05-31 21:30:48 【问题描述】:

数据:

id  uid     type

1   20      A
2   20      B
3   20      A
4   6       A
5   1       A
6   3       A
7   6       A
8   1       B

场景:

我想按type 分组并按id 排序。我正在使用 group by 对uid 进行分组。

当前查询:

SELECT
    type,
    GROUP_CONCAT(DISTINCT uid) AS users,
    COUNT(type) AS typeCount
FROM
    `test2`
GROUP BY
    type

问题:

但是uid的顺序不对,应该是按照id降序排列的。

预期结果:

type    users       typeCount
A       6,3,1,20    6
B       1,20        2

我的结果:

type    users       typeCount
A       20,6,1,3    6
B       20,1        2

【问题讨论】:

按照id降序 在下面检查我的答案,这应该可以解决问题 是的,我正在尝试所有答案,感谢您的帮助。 "我想按类型分组,并按降序获取所有的uid" "应该按照id降序排列。"不一致。 【参考方案1】:

尝试类似:

 SELECT
    type,
    GROUP_CONCAT(DISTINCT uid) AS users,
    COUNT(type) AS typeCount
FROM
    (SELECT type, uid
     FROM `test2`
     ORDER BY uid desc) mytableAlias
GROUP BY
    type

【讨论】:

【参考方案2】:

你可以像 Sampson 在这篇文章中建议的那样做:

mysql: Sort GROUP_CONCAT values

这里是 MySQL 文档的链接

http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function%5Fgroup-concat

这是他给出的例子:

SELECT student_name,
  GROUP_CONCAT(DISTINCT test_score ORDER BY test_score DESC SEPARATOR ' ')
  FROM student
  GROUP BY student_name;

您只需要根据自己的需要进行调整。

希望对你有帮助

【讨论】:

【参考方案3】:

MySQL 的奥秘。

实际上引擎按 ASC 顺序取第一个值,无论您是按 ID 要求 DESC,所以首先“翻转”表格,然后:

SELECT
    type,
    GROUP_CONCAT(DISTINCT uid ORDER BY id DESC) AS users,
    COUNT(type) AS typeCount
FROM
    (SELECT * FROM `test2` ORDER BY id DESC) test2
GROUP BY
    type

SQLFiddleDemo

【讨论】:

它给出了您预期的结果。 不,它给了3,1,6,20 在我的 MySQL 5.6.17 上返回 A: 6,3,1,20 小提琴工作正常,我有相同的版本。我不明白,你有什么想法吗? 你的第二段完全是错误的,使用子查询是不必要的和误导性的。【参考方案4】:

这个不需要子查询。根据您的描述,您只需要在GROUP_CONCAT() 中添加一个ORDER BY

SELECT type,
        GROUP_CONCAT(DISTINCT uid ORDER BY uid DESC) AS users,
        COUNT(type) AS typeCount
FROM `test2`
GROUP BY type;

在 MySQL 中,避免不必要的子查询是个好主意,因为数据库引擎会将它们具体化。

【讨论】:

【参考方案5】:

@mitkosoft 的回答已经对了。

我发布这个只是为了分析正确的预期结果。

从下面的输出我们可以看出,对于type 'A' group,在DISTINCT 生效前,ORDER BY id DESC 后的行是:

6 3 1 6 20 20

那么 DISTINCT 可以产生两种可能的结果:6,3,1,20 或 3,1,6,20。

生产哪一个是不确定的,与实现有关。否则,我们不能依赖它。

因此,“A”组的预期结果应该是 6,3,1,20 或 3,1,6,20。两者都正确。

mysql> SELECT * FROM test2;
+------+------+------+
| id   | uid  | type |
+------+------+------+
|    1 |   20 | A    |
|    2 |   20 | B    |
|    3 |   20 | A    |
|    4 |    6 | A    |
|    5 |    1 | A    |
|    6 |    3 | A    |
|    7 |    6 | A    |
|    8 |    1 | B    |
+------+------+------+
8 rows in set (0.00 sec)

mysql> SELECT uid FROM test2 WHERE type='A' ORDER BY id DESC;
+------+
| uid  |
+------+
|    6 |
|    3 |
|    1 |
|    6 |
|   20 |
|   20 |
+------+
6 rows in set (0.00 sec)

【讨论】:

以上是关于在 group_concat 中排序的主要内容,如果未能解决你的问题,请参考以下文章

在带有函数的 MySQL GROUP_CONCAT 中排序

在 SQLite 中,多个列的排序方式是不是与 group_concat 相同?

MySQL中GROUP_CONCAT中排序

MySQL group_concat() 按 case 语句值排序

MySQL中GROUP_CONCAT中排序

GROUP_CONCAT的进阶使用