2009-10-05 8 views
6

Potrzebuję tej funkcji, ale MySQL nie obsługuje jej w tej chwili.Jak zhakować MySQL GROUP_CONCAT, aby pobrać ograniczoną liczbę wierszy?

Używam GROUP_CONCAT(CONCAT(...)) do generowania materiałów przypominających xml.

Ale kiedy rozmiar przekracza limit, xml jest po prostu zepsuty!

Muszę więc jakoś sprawić, by odzyskiwał tylko 5 rzędów!

+0

wzrost group_concat_max_len wartość w my.cnf – Omesh

+1

może być można uzyskać tutaj odpowiedzi http://stackoverflow.com/questions/3378324/limit-ignored-in-query-with-group-concat http://stackoverflow.com/questions/23608464/group-concat-with-limit –

Odpowiedz

2

Użyj tymczasowej tabeli/podkwerendy do ograniczenia wyników? Nie widząc zapytania, trudno będzie udzielić rzetelnej porady na temat tej trasy.

Jednak ustawienie group_concat_max_len może okazać się bardziej przydatne. Kontroluje maksymalną długość operacji GROUP_CONCAT, w długości łańcucha. Podnieś go, aby zapobiec zerwaniu, gdy nie możesz sobie pozwolić na ograniczenie wyników.

2

Niezupełnie odpowiedź na swoje pytanie, ale ref dla innych ludzi, którzy również chcieliby skorzystać z klauzuli LIMIT w GROUP_CONCAT():

feature-request został złożony dawno programistów MySQL. jeszcze nie wdrożone :-(

4

przykład dla Karola odpowiedź:

podstawowy:

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

rozszerzony:

CAST może być przydatna, jeśli wynikiem są obcinane przez bufor:

SELECT CAST(GROUP_CONCAT(field) AS CHAR(2048)) FROM (SELECT field FROM table LIMIT 200) 
+0

Tak, to zadziała. Ale będzie potrzebować bardziej złożonej konstrukcji dla zapytania z 'GROUP BY'. –

+0

Mam błąd dla "Każda wyprowadzona tabela musi mieć swój własny alias" podczas korzystania z pierwszego zapytania. Aby to naprawić, zmieniłem go na "SELECT GROUP_CONCAT (field) FROM (pole SELECT z tabeli LIMIT 200) AS alias" Dzięki za odpowiedź. – Henry

15

Pracowałem nad tym przy użyciu SUBSTRING_INDEX.

Na przykład:

SELECT SUBSTRING_INDEX(GROUP_CONCAT(Field1 SEPARATOR ','), ',', [# of elements to return]) 
FROM Table1; 
+0

Zwraca obiekt typu blob, ale ten działa. –

0

Dla tych przypadkach, gdy nie można użyć tabeli temp, najlepszym sposobem znam jest wybranie niejasne separator, a następnie obciąć począwszy od pierwszego wystąpienia wspomnianego znaku. W tym przykładzie użyto znaku NUL.

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

Gdzie field to nazwa pola, 5 jest liczba wyników.

Wadą jest to, że pierwszy wiersz zawiera ten znak, będzie to wynik częściowy.

Obejście problemu zastąpiłoby '\0' dłuższym losowym ciągiem.

Warto wiedzieć, że field może zostać zastąpiony, aby dodać więcej informacji za pomocą concat.

Należy pamiętać, że domyślnie group_concat_max_len ma 1024 znaki, więc jeśli chcesz uzyskać więcej, powinieneś sprawdzić, czy zmienia się to globalnie, czy w aplikacji.

0

Można symulować podzielono ROW_NUMBER pomocą zmiennych użytkownika, a następnie ograniczyć wiersze i zastosować group_concat:

Rozważmy następującą tabelę:

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

i dane:

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); 

I chcemy jest górą 3 (w kolejności ostatniego id) wartość na kategorię konkatenacji:

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; 

wyjściowa:

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

Oto demo tego.