2011-09-21 40 views
16

Tôi có một câu hỏi như thế này:Nhiều GROUP_CONCAT trên các lĩnh vực khác nhau sử dụng 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 

Và việc truy vấn, nhưng không như mong đợi, bởi vì nếu tôi có một sản phẩm với 5 mặt và 1 hình ảnh (giả sử một hình ảnh với id = 7), sau đó tôi nhận được một cái gì đó như thế này trong "images_id":
"7,7,7,7,7"
Nếu tôi có 2 hình ảnh (7 và 3) sau đó tôi nhận được một cái gì đó như:
"7,7,7,7,7,3,3,3,3,3"
và ở khía cạnh tôi nhận được một cái gì đó như:
"8,7,6,5,4,8,7,6,5,4"

Tôi nghĩ MySQL đang thực hiện một số loại hình công đoàn của differents các hàng được truy vấn trả về và sau đó ghép tất cả mọi thứ.

kết quả mong đợi của tôi là (cho ví dụ cuối cùng):

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

tôi có thể có được điều đó bằng cách sử dụng DISTINCT trong GROUP_CONCAT, nhưng sau đó tôi có một vấn đề khác: Nếu tôi có hai hình ảnh có cùng tên, một trong số đó có tên giống như sau:
images_id = "7,3,5"
images_title = "Tiêu đề7and3, Tiêu đề5"

Vì vậy, tôi bỏ lỡ mối quan hệ giữa images_id và images_title.

Có ai biết nếu có thể thực hiện truy vấn này trong MySQL không?

Có thể tôi đang làm phức tạp mọi thứ mà không có bất kỳ lợi ích thực sự nào. Tôi đang cố gắng thực hiện chỉ một truy vấn vì hiệu suất, nhưng bây giờ tôi không chắc chắn nếu nó thậm chí còn nhanh hơn để thực hiện hai truy vấn (một để chọn các khía cạnh và một cho các hình ảnh chẳng hạn).

Hãy giải thích bạn nghĩ gì là giải pháp tốt nhất cho vấn đề này và tại sao.

Cảm ơn!

Trả lời

8

Bạn sẽ cần phải nhận được từng nhóm riêng biệt:

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

Tôi không hiểu truy vấn của bạn rất tốt, nhưng có vẻ rất phức tạp, ý tôi là, chúng tôi cần một nhóm phụ với một nhóm cho mỗi concat? Nó trông giống như một cái gì đó rất chậm, không phải là nhanh hơn 2 truy vấn? – Enrique

+2

@Enrique, nó không phải là về tốc độ, đó là về sự chính xác. Nếu mã của tôi không cần phải thực sự làm việc tôi có thể làm mọi thứ ngay lập tức. – Johan

+0

@Enrique, Bạn không cần chọn phụ cho mỗi nhóm concat, chỉ dành cho những bảng mà đối sánh với p.id trả về nhiều hơn 1 hàng trên mỗi p.id. – Johan

1

Nếu vấn đề là tốc độ, sau đó nó có thể nhanh hơn rất nhiều chỉ đơn giản là chọn tất cả các dữ liệu bạn cần như hàng riêng biệt, và làm việc nhóm trong việc áp dụng, ví dụ:

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

Sau đó, trong ứng dụng:

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

Chỉ cần thêm DISTINCT.

Ví dụ:
GROUP_CONCAT(DISTINCT image.id) AS images_id

+0

+1, Nó cũng hoạt động cho SQLite3 – user457015

+0

Tôi nghĩ rằng điều này cần phải được mở rộng theo. ''DISTINCT' => GROUP_CONCAT (DISTINCT image.id) AS images_id' không phải là cú pháp SQL, và MySQL 5.1 ném một lỗi cú pháp. Người hỏi không đề cập đến bất kỳ ngôn ngữ lập trình nào, vì vậy nếu câu trả lời này không phải là SQL, nó cần được chuyển đổi hoặc giải thích. – Animism

+0

Nhiều 'GROUP_CONCAT' không có hàng bổ sung. +1 –

4

Bạn có thể thêm chỉ từ khóa DISTINCT, bạn sẽ nhận được kết quả mong muốn của bạn.

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 
Các vấn đề liên quan