[英]MySQL JOIN: Select a row if a bool column is 1, otherwise select the first row
I have two tables: products(id)
and product_images(id, parent_id, src, is_default)
我有两个表:
products(id)
和product_images(id, parent_id, src, is_default)
Each product has n
images. 每个产品有
n
张图像。
I want to get all products and one image for each of them. 我想获得所有产品和每个产品的一个图像。
If the column is_default
is 1( BOOL
), then get that image, otherwise get the first one. 如果
is_default
1( BOOL
),则获取该图像,否则获取第一个图像。
My query looks like this 我的查询看起来像这样
SELECT
main.*,
images.id image_id, images.src image_src
FROM products main
LEFT JOIN product_images images ON main.id = images.parent_id AND images.is_default = 1
GROUP BY main.id
ORDER BY main.id DESC
Obviously the JOIN
condition is not right and I can't figure it out. 显然,
JOIN
条件不正确,我无法弄清楚。
Hope you can help, 希望您能提供帮助,
Thank you. 谢谢。
I suppose that the first image is the one with the lowest ID, I would start with this query: 我想第一个图像是ID最低的图像,我将从以下查询开始:
SELECT
parent_id,
COALESCE(
MIN(CASE WHEN is_default=1 THEN ID END),
MIN(id)
) AS image_id
FROM product_images
GROUP BY parent_id
this will return the image where is_default = 1, if there's no default MIN(case when...) will be null and then COALESCE will select just MIN(id). 如果没有默认值MIN(case when ...)将为null,然后COALESCE仅选择MIN(id),则它将返回is_default = 1的图像。 Then you can join your query with the previous subquery:
然后,您可以将查询与先前的子查询合并:
SELECT main.*, images.id image_id, images.src image_src
FROM
products main LEFT JOIN JOIN (
SELECT
parent_id,
COALESCE(
MIN(CASE WHEN is_default=1 THEN ID END),
MIN(id)
) AS min_image_id
FROM product_images
GROUP BY parent_id
) fi ON fi.parent_id = main.id
LEFT JOIN product_images images
ON images.id = fi.min_image_id
Using GROUP_CONCAT. 使用GROUP_CONCAT。
This gets all the image details for each main ordered by is_default descending, and then by id. 这将获取每个主图像的所有图像详细信息,这些图像详细信息按is_default降序排序,然后按id排序。 So if there are no records with is_default set to 1 then it will get the first image first.
因此,如果没有将is_default设置为1的记录,则它将首先获取第一张图像。 Then uses SUBSTRING_INDEX to get the first details.
然后使用SUBSTRING_INDEX获取第一个详细信息。
Note that if images.src can contain a comma you might want to use a different delimiter. 请注意,如果images.src可以包含逗号,则可能需要使用其他定界符。
SELECT
main.*,
SUBSTRING_INDEX(GROUP_CONCAT(images.id ORDER BY images.is_default DESC, images.id), ',', 1) AS image_id,
SUBSTRING_INDEX(GROUP_CONCAT(images.src ORDER BY images.is_default DESC, images.id), ',', 1) AS image_src
FROM products main
LEFT JOIN product_images images ON main.id = images.parent_id
GROUP BY main.id
ORDER BY main.id DESC
You can grab the single image information in a subquery: 您可以在子查询中获取单个图像信息:
SELECT main.*,
(SELECT images.id
FROM product_images image
WHERE main.id = images.parent_id
AND images.is_default = 1
ORDER BY images.id
) image_id,
(SELECT images.src
FROM product_images image
WHERE main.id = images.parent_id
AND images.is_default = 1
ORDER BY images.id
) image_src
FROM products main
You will need a sub-query. 您将需要一个子查询。 I think this is the simplest solution.
我认为这是最简单的解决方案。
SELECT
*
FROM (
SELECT main.*, images.id image_id, images.src image_src
FROM products as main
LEFT JOIN product_images as images ON main.id = images.parent_id
ORDER BY images.is_default DESC
) as t
GROUP BY t.id
This does what you want, but orders by the images.is_default desc, so that if the is_default is 1, then this will show at the top. 这可以满足您的要求,但是按images.is_default desc排序,因此,如果is_default为1,则它将显示在顶部。 The outer query
GROUP BY
will force the one with the is_default to be selected if is_default
is set. 外部查询
GROUP BY
将迫使如果将被选择的一个与所述is_default is_default
被设置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.