Как взломать MySQL GROUP_CONCAT для получения ограниченного числа строк? - PullRequest
6 голосов
/ 06 октября 2009

Мне как-то нужна эта функция, но MySQL не поддерживает ее в данный момент.

Я использую GROUP_CONCAT(CONCAT(...)) для создания XML-подобных вещей.

Но когда размер превышает лимит, xml просто нарушается!

Так что мне нужно как-то заставить его получить только 5 строк!

Ответы [ 6 ]

15 голосов
/ 12 июня 2012

Я работал над этим, используя SUBSTRING_INDEX.

Например:

SELECT SUBSTRING_INDEX(GROUP_CONCAT(Field1 SEPARATOR ','), ',', [# of elements to return])
FROM Table1;
4 голосов
/ 05 января 2012

Пример ответа Чарльза:

основной:

SELECT GROUP_CONCAT( field ) FROM ( SELECT field FROM table LIMIT 200 )

расширен:

CAST может быть полезен, если результат урезан буфером:

SELECT CAST( GROUP_CONCAT( field ) AS CHAR(2048) ) FROM ( SELECT field FROM table LIMIT 200 )
2 голосов
/ 05 мая 2010

Не совсем ответ на ваш вопрос, но ссылка для других людей, которые также хотели бы использовать предложение LIMIT в GROUP_CONCAT ():

A feature-request был давно подан разработчикам MySql. Еще не реализовано: - (

2 голосов
/ 06 октября 2009

Использовать временную таблицу / подзапрос для ограничения результатов? Не видя вашего запроса, будет сложно дать надежный совет по этому маршруту.

Однако, вы можете найти параметр group_concat_max_len более полезным. Он контролирует максимальную длину операции GROUP_CONCAT в длине строки. Поднимите его, чтобы предотвратить битые GROUP_CONCAT с, когда вы не можете позволить себе ограничить результаты.

0 голосов
/ 13 мая 2017

Вы можете смоделировать номер строки с использованием пользовательских переменных, а затем ограничить число строк и применить group_concat:

Рассмотрим следующую таблицу:

create table your_table (
    id int primary key autoincrement,
    category int,
    value int
);

и данные:

insert into your_table (category, value) 
values
(1,  1), (1,  2), (1,  3), (1,  4), (1,  5),
(2,  6), (2,  7), (2,  8), (2,  9), (2, 10),
(3, 11), (3, 12), (3, 13), (3, 14), (3, 15);

И мы хотим, чтобы это было верхнее 3 (в порядке последнего идентификатора) значение для каждой категории:

select category, 
    group_concat(value order by id desc) as value_con
from (
    select t.*,
        @rn := if(@category = category, @rn + 1, if(@category := category,1, 1)) as seqnum
    from your_table t
    cross join (select @category := null, @rn := 0) x
    order by t.category, t.id desc
    ) t
where seqnum <= 3
group by category;

Выход:

category    value_con
1           5,4,3
2           10,9,8
3           15,14,13

Вот демоверсия этого.

0 голосов
/ 28 августа 2014

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

select substring_index(group_concat(field separator '\0'), '\0', 5) from table;

Где field - имя поля, 5 - количество результатов.

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

Обходной путь - заменить '\0' более длинной случайной строкой.

Приятно осознавать, что field можно заменить на дополнительную информацию, используя concat.

Имейте в виду, что по умолчанию group_concat_max_len установлено значение 1024 символа, поэтому вам следует изменить его глобально или в своем приложении, если вы хотите большего.

...