简体   繁体   English

MySQL JOIN:如果bool列为1,则选择一行,否则选择第一行

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM