Несколько GROUP_CONCAT на разных полях с использованием MySQL - PullRequest
20 голосов
/ 22 сентября 2011

У меня такой запрос:

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

И запрос работает, но не так, как ожидалось, потому что, если у меня есть продукт с 5 гранями и 1 изображением (предположим, изображение с id = 7), я получаю что-то вроде этого в "images_id":
"7,7,7,7,7"
Если у меня есть 2 изображения (7 и 3), я получаю что-то вроде:
"7,7,7,7,7,3,3,3,3,3"
и в гранях я получаю что-то вроде:
"8,7,6,5,4,8,7,6,5,4"

Я думаю, что MySQL объединяет строки разностей, возвращаемых запросом, и затем объединяет все.

Мой ожидаемый результат (для последнего примера):

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

Я могу получить это, используя DISTINCT в GROUP_CONCAT, но тогда у меня есть другая проблема: Если у меня есть два изображения с одинаковым названием, одно из них пропущено, а затем я получаю что-то вроде:
images_id = "7,3,5"
images_title = "Title7and3, Title5"

Так что мне не хватает отношения между images_id и images_title.

Кто-нибудь знает, возможно ли сделать этот запрос в MySQL?

Может быть, я все усложняю без каких-либо реальных выгод. Я пытаюсь выполнить только один запрос из-за производительности, но теперь я не уверен, что еще быстрее выполнить два запроса (один для выбора фасетов, а другой для изображений, например).

Пожалуйста, объясните, что, по вашему мнению, является лучшим решением для этого и почему.

Спасибо!

Ответы [ 4 ]

41 голосов
/ 11 июня 2012

Просто добавьте DISTINCT.

Пример:
GROUP_CONCAT(DISTINCT image.id) AS images_id

9 голосов
/ 22 сентября 2011

Вам нужно будет получить каждую группу отдельно:

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
...
4 голосов
/ 13 мая 2013

Вы можете добавить только ключевое слово DISTINCT, вы получите желаемый результат.

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
1 голос
/ 15 октября 2011

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

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

Затем вприменение:

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