2016-02-21 7 views
4

набора данных:Сортировка данных в группах

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 

Я хочу группе activity и postid, имея результат в порядке убывания id. И хотите иметь последние id и uid для каждой группы. Я не понимаю, почему этот запрос не возвращает ожидаемый результат.

ответ

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 
+0

Нет, чувак, я не могу получить 'MAX (uid)', мне нужен последний 'uid' (последний по' id'). И никакой 'uid' не увеличивается, это FK из другой таблицы. – Shaharyar

+0

Мой плохой. Обновлен ответ. –

+0

Ну его хороший подход и решает проблему. Но мне любопытно, почему он не сортирует строки перед группировкой? Даже после моего подзапроса подход их сортировать? – Shaharyar

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 s в любом случае).

+0

Какова длина по умолчанию для 'GROUP_CONCAT()'? – Shaharyar

+0

@Shaharyar. , , http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_group_concat_max_len. Я подчеркиваю, что это влияет на вашу существующую 'group_concat()', а также вторую предложенную здесь. –