Сортировка в group_concat

Данные:

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

person Shaharyar    schedule 19.02.2016    source источник
comment
По убыванию согласно id   -  person Shaharyar    schedule 19.02.2016
comment
Проверьте мой ответ ниже, это должно помочь   -  person zachu    schedule 19.02.2016
comment
Да, я пробую все ответы, ценю вашу помощь.   -  person Shaharyar    schedule 19.02.2016
comment
Я хочу сгруппировать по типу и получить все uid в порядке убывания, он должен быть в порядке убывания в соответствии с id. непоследовательный.   -  person Dylan Su    schedule 19.02.2016


Ответы (5)


Тайна MySQL.

На самом деле движок принимает первое значение в порядке ASC, независимо от того, что вы запрашиваете 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

демонстрация SQLFiddle

person mitkosoft    schedule 19.02.2016
comment
это дает ожидаемый результат. - person mitkosoft; 19.02.2016
comment
Нет, это дает 3,1,6,20 - person Shaharyar; 19.02.2016
comment
В моем MySQL 5.6.17 возвращается A: 6,3,1,20 - person mitkosoft; 19.02.2016
comment
Скрипка работает нормально, у меня такая же версия. Я не понимаю, у тебя есть идеи? - person Shaharyar; 19.02.2016
comment
Ваш второй абзац просто неверен, а использование подзапроса не нужно и вводит в заблуждение. - person Gordon Linoff; 19.02.2016
comment
не согласен - mysql выполняет сканирование таблицы в порядке возрастания, независимо от того, есть ли у вас запрос в порядке убывания в group_concat. без переворачивания таблицы запрос вернет 3,1,6,20, что не является ожидаемым результатом. - person mitkosoft; 19.02.2016

Ответ от @mitkosoft уже правильный.

Я публикую это только для того, чтобы проанализировать правильный ожидаемый результат.

Из следующего вывода мы видим, что для группы типа «A» до того, как DISTINCT вступит в силу, после ORDER BY id DESC строки следующие:

6 3 1 6 20 20

Тогда DISTINCT может выдать два возможных результата: 6,3,1,20 или 3,1,6,20.

Какой из них произведен, не определено и связано с реализацией. В противном случае, мы не можем полагаться на это.

Поэтому ожидаемый результат для группы "А" должен быть 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)
person Dylan Su    schedule 19.02.2016

Вы можете сделать что-то вроде предложенного Сэмпсоном в этом посте:

MySQL: сортировка значений GROUP_CONCAT

Вот ссылка на документы 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;

Вам просто нужно настроить его под свои нужды.

Надеюсь это поможет

person zachu    schedule 19.02.2016

Для этого не требуется подзапрос. Из вашего описания вам просто нужно ORDER BY в GROUP_CONCAT():

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

В MySQL рекомендуется избегать ненужных подзапросов, потому что механизм базы данных материализует их.

person Gordon Linoff    schedule 19.02.2016

Попробуйте что-то вроде:

 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
person SMA    schedule 19.02.2016