分组

时间:2016-02-21 17:37:17

标签: mysql sql group-by group-concat

数据集:

id  uid     activity    postid  
1   20      A           1
2   20      A           1
3   6       A           1
4   3       A           1
5   6       A           1
6   13      A           1
7   13      B           1
8   18      B           1
9   18      B           1
10  1       A           1

当前结果:

id  uid     uid_list        groupCount  activity    postid
9   18      18,13           3           B           1
1   20      1,13,6,3,20     7           A           1

预期结果:

id  uid     uid_list        groupCount  activity    postid
9   18      18,13           3           B           1
10  1       1,13,6,3,20     7           A           1

我的查询:

SELECT
    id,
    uid,
    GROUP_CONCAT(DISTINCT uid ORDER BY id DESC) as uid_list,
    COUNT(*) as groupCount,
    activity,
    postid
FROM (
    SELECT *
    FROM `user_activities`
    ORDER BY id DESC) as tbl
GROUP BY
    activity, postid
ORDER BY
    id DESC

我希望按activitypostid进行分组,同时按id降序排列结果。并希望每个群组都拥有最新的iduid。我不明白为什么这个查询不会返回预期的输出。

2 个答案:

答案 0 :(得分:2)

根据我的理解,id价值正在增加。要获取最新值,您可以使用聚合函数MAX()

此外,您的内部查询与排序是不必要的,因为在构建id的结果时,引擎必须按GROUP_CONCAT()对结果集进行排序。

要检索特定uid列的id,您需要自行加入同一个表格。

SELECT
    a.id, b.uid, a.uid_list, a.groupcount, a.activity, a.postid
FROM (
    SELECT
        MAX(id) as id,
        GROUP_CONCAT(DISTINCT uid ORDER BY id DESC) as uid_list,
        COUNT(*) as groupCount,
        activity,
        postid
    FROM user_activities a
    GROUP BY
        activity, postid
    ) a
    INNER JOIN user_activities b ON a.id = b.id

答案 1 :(得分:0)

可能最简单的方法是group_concat() / substring_index()诀窍:

SELECT MAX(ID) as id,
       SUBSTRING_INDEX(GROUP_CONCAT(uid ORDER BY ID DESC), ',', 1) as uid,
       GROUP_CONCAT(DISTINCT uid ORDER BY id DESC) as uid_list,
       COUNT(*) as groupCount,
       activity, postid
FROM user_activities ua
GROUP BY activity, postid
ORDER BY id DESC;

这种方法存在一些限制,因为GROUP_CONCAT()具有中间值的最大长度。通常默认值是足够的,但如果许多行与每个组匹配,则可能需要更改该值(并且您已经对uid的列表存在此问题)。