2011-09-21 20 views
16

Mam kwerendy tak:Multiple GROUP_CONCAT na różnych polach MySQL

SELECT product.id, 
     GROUP_CONCAT(image.id) AS images_id, 
     GROUP_CONCAT(image.title) AS images_title, 
     GROUP_CONCAT(facet.id) AS facets_id 
... 
GROUP BY product.id 

I kwerenda działa, ale nie zgodnie z oczekiwaniami, bo jeśli mam produkt o 5 aspektach i 1 obrazek (załóżmy obraz id = 7), a następnie otrzymuję coś takiego w "images_id":
"7,7,7,7, 7"
Jeśli mam 2 obrazy (7 i 3), otrzymuję coś takiego:
"7,7,7,7,7,3,3,3,3,3"
iw aspektach mam coś takiego:
„8,7,6,5,4,8,7,6,5,4”

myślę MySQL jest dokonanie pewnego rodzaju unii zróżnicowanych wiersze zwracane przez zapytanie, a następnie łączenie wszystkich.

Moja Oczekiwany wynik to (za ostatni przykład):

images_id = "7,3"
facets_id = "8,7,6,5,4"

mogę otrzymać, że za pomocą DISTINCT w GROUP_CONCAT, ale wtedy mam inny problem: Jeśli mam dwa obrazy o tym samym tytule, jeden z nich jest pomijany, a następnie otrzymuję coś w rodzaju:
images_id = "7,3,5"
images_title = "Title7and3, Title5"

Tęsknię za relacją pomiędzy images_id a images_title.

Czy ktoś wie, czy możliwe jest wykonanie tego zapytania w MySQL?

Może komplikuję wszystko bez żadnych rzeczywistych korzyści. Próbuję wykonać tylko jedną kwerendę, ponieważ wydajność, ale teraz nie jestem tak pewien, czy jest jeszcze szybciej wykonać dwa kwerendy (jeden do wyboru aspektów, a drugi do obrazów na przykład).

Proszę wyjaśnić, co według Ciebie jest najlepszym rozwiązaniem dla tego i dlaczego.

Dzięki!

Odpowiedz

8

Musisz dostać każdą grupę oddzielnie:

SELECT 
    p.id, 
    images_id, 
    images_title, 
    facets_id, 
    ... 
FROM PRODUCT p 
JOIN (SELECT product.id, GROUP_CONCAT(image.id) AS images_id 
     FROM PRODUCT GROUP BY product.id) a on a.id = p.id 
JOIN (SELECT product.id, GROUP_CONCAT(image.title) AS images_title 
     FROM PRODUCT GROUP BY product.id) b on b.id = p.id 
JOIN (SELECT product.id, GROUP_CONCAT(facet.id) AS facets_id 
     FROM PRODUCT GROUP BY product.id) b on c.id = p.id 
... 
+0

Nie rozumiem twojego zapytania bardzo dobrze, ale wygląda na bardzo skomplikowane, to znaczy, potrzebujemy selekcji podrzędnej z grupą dla każdego konkata? Wygląda na coś bardzo powolnego, nie jest szybsze 2 zapytania? – Enrique

+2

@ Eriqueque, nie chodzi o szybkość, chodzi o poprawność. Jeśli mój kod nie musi działać, mogę zrobić wszystko natychmiast. – Johan

+0

@Enrique, Nie musisz wybierać podkategorii dla każdej konkatycji grupy, tylko dla tych tabel, w których dopasowanie przeciwko p.id zwraca więcej niż 1 wiersz na p.id. – Johan

1

Jeśli problem jest szybkość, to może być dużo szybciej po prostu zaznaczyć wszystkie potrzebne dane jako oddzielne wiersze i zrobić grupowanie we wniosku, tj:

SELECT product.id, image.id, image.title, facet.id 

Następnie w aplikacji:

foreach row: 
    push product_id onto list_of_product_ids 
    push image_id onto list_of_image_ids 
etc. 
30

Wystarczy dodać DISTINCT.

Przykład:
GROUP_CONCAT(DISTINCT image.id) AS images_id

+0

+1, działa również dla SQLite3 – user457015

+0

Myślę, że należy to rozszerzyć. ''DISTINCT' => GROUP_CONCAT (DISTINCT image.id) AS images_id' nie wydaje się być składnią SQL, a MySQL 5.1 zgłasza błąd składni. Pytający nie wymienił żadnych języków programowania, więc jeśli ta odpowiedź nie jest SQL, należy ją przekonwertować lub wyjaśnić. – Animism

+0

Wiele 'GROUP_CONCAT's bez dodatkowych wierszy. +1 –

4

Można dodać tylko DISTINCT, dostaniesz wyniki pragnienie.

SELECT tb_mod.*, tb_van.*, 
GROUP_CONCAT(DISTINCT tb_voil.vt_id) AS voil, 
GROUP_CONCAT(DISTINCT tb_other.oa_id) AS other, 
GROUP_CONCAT(DISTINCT tb_ref.rp_id) AS referral 
FROM cp_modules_record_tbl tb_mod 
LEFT JOIN cp_vane_police_tbl tb_van ON tb_van.mr_id= tb_mod.id 
LEFT JOIN cp_mod_voilt_tbl tb_voil ON tb_voil.mr_id= tb_mod.id 
LEFT JOIN cp_mod_otheraction_tbl tb_other ON tb_other.mr_id= tb_mod.id 
LEFT JOIN cp_mod_referral_tbl tb_ref ON tb_ref.mr_id= tb_mod.id 
WHERE tb_mod.mod_type = 2 GROUP BY tb_mod.id 
Powiązane problemy