开发者

mysql group_concat

I have two tables.

products

id  title      image_ids
---------------------
1   myproduct  1,2,3

images

id  title     file_name
-------------------------
1   myimage   myimage.jpg
2   myimage2  myimage2.jpg
3   myimage3  myimage3.jpg

I want to query so that the names of the images are concatenated into a single field for each product reference.

This query doesn't work

   SELECT products.title,
          products.image_ids,
          GROUP_CONCAT(images.file_name)
     FROM products
LEFT JOIN images ON images.id IN (products.image_ids)
    WHERE products.id = 1
    GROUP BY products.id

This one does:

   SELECT products.title,
          products.image_ids,
          GROUP_CONCAT(images.file_name)
     FROM products
LEFT JOIN images ON images.id IN (1,2,3)
    WHERE products.id = 1
    GROUP BY products.id

And produces the desired results

title       image_ids  file_names
--------------------------------------------------------------
myproduct   1,2,3      myimage.jpg,myimage2.jpg,myimage3.jpg 

Why doesn't the first query w开发者_JS百科ork when it is asking the same thing as the second query and how can I make it work.


IN does not work for comma-separated lists of values.

Basically, you are not comparing integers, you are comparing strings:

SELECT  1 IN (1, 2, 3) -- True
SELECT  1 IN ('1, 2, 3') -- False ('1' <> '1, 2, 3')

Use FIND_IN_SET instead:

SELECT  products.title,products.image_ids, GROUP_CONCAT(images.file_name)
FROM    products
LEFT JOIN
        images
ON      FIND_IN_SET(images.id, products.image_ids)
WHERE   products.id = 1
GROUP BY
        products.id

This, however, is not the best solution performance-wise since FIND_IN_SET is non-sargable. It will require a full table scan on images.

If you have some reasonable limit on the number of values in products.image_ids (say, no more than 5 images per product), you can use this query instead:

SELECT  products.title,products.image_ids, GROUP_CONCAT(images.file_name)
FROM    (
        SELECT  1 AS n
        UNION ALL
        SELECT  2 AS n
        UNION ALL
        SELECT  3 AS n
        UNION ALL
        SELECT  4 AS n
        UNION ALL
        SELECT  5 AS n
        ) q
CROSS JOIN
        products
LEFT JOIN
        images
ON      SUBSTRING_INDEX(SUBSTRING_INDEX(image_ids, ',', n), ',', 1)
WHERE   products.id = 1
        AND SUBSTRING_INDEX(image_ids, ',', n) <> SUBSTRING_INDEX(image_ids, ',', n - 1)
GROUP BY
        products.id
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜