使用 GROUP BY 获取具有最高值的条目
Using GROUP BY to get the entry with the highest value
我需要为每个产品创建一个带有预览图像的产品列表。
我有一个非常简单的产品数据结构。一个 table 用于产品,一个 table 用于产品图像。一个产品可以有任意数量的图像。结构如下所示:
PRODUCT
id | name
1 Test Product A
2 Test Product B
3 Test Product C
PRODUCTIMAGE
id | productId | file | priority
1 1 foo.jpg 0
2 1 bar.jpg 1
3 2 something.png 1
4 2 yada.png 0
5 1 yougettheidea.gif 2
非常简单。唯一值得一提的是 productimages 有一个“优先级”,即 TINYINT
来确定给定产品的图像显示顺序。思路是:优先级越高,该图片在详情页的商品图片列表中应该越早显示。但是对于我们即将创建的这个产品列表,我只需要每个产品一张预览图片。
正如最初所述,我的目标是获取所有产品的列表。那么让我们从简单的开始:
SELECT *
FROM product
现在我也想在产品页面显示一张预览图,所以需要一点加入:
SELECT `p`.*,
`pi`.`file` `previewImage`
FROM `product` `p`
LEFT JOIN `productImage` `pi` ON (`pi`.`productId` = `p`.`id`)
GROUP BY `p`.`id`
到目前为止一切顺利,这为我提供了每个产品一张预览图像以显示在产品列表中。还差一步:我要每个产品优先级最高的预览图作为预览图。所以我尝试使用子查询以所需的优先顺序获取产品图片:
SELECT `p`.*,
`pi`.`file` `previewImage`
FROM `product` `p`
LEFT JOIN (
SELECT *
FROM `productImage`
ORDER BY `priority` DESC
) `pi` ON (`pi`.`productId` = `p`.`id`)
GROUP BY `p`.`id`
但出于某种原因,这并没有(可靠地)为我提供每个产品具有最高优先级的产品图像。这是为什么?我认为 GROUP BY
选择了错误的 productImage 条目来保留,但为什么呢?它不应该选择第一个吗,由于子查询应该是优先级最高的那个?
您的分组依据是部分分组依据。您按 product.id
分组,因此 MySQL 将按产品对结果进行分组,但在每个组中,可以自由 return 来自 productimage
table 的任何行。要获得确定性结果,table 中的每一列都需要包含在聚合函数(MIN、MAX 等)中,但这不会为您提供具有最高优先级的图像。
也就是说,如果您只想要 productimage
table 中的一列,您可以在 select:
中使用子查询
select product.*, (
select file
from productimage
where productimage.productid = product.id
order by priority desc
limit 1 -- this is the important bit
) as productimage_file
from product
我需要为每个产品创建一个带有预览图像的产品列表。
我有一个非常简单的产品数据结构。一个 table 用于产品,一个 table 用于产品图像。一个产品可以有任意数量的图像。结构如下所示:
PRODUCT
id | name
1 Test Product A
2 Test Product B
3 Test Product C
PRODUCTIMAGE
id | productId | file | priority
1 1 foo.jpg 0
2 1 bar.jpg 1
3 2 something.png 1
4 2 yada.png 0
5 1 yougettheidea.gif 2
非常简单。唯一值得一提的是 productimages 有一个“优先级”,即 TINYINT
来确定给定产品的图像显示顺序。思路是:优先级越高,该图片在详情页的商品图片列表中应该越早显示。但是对于我们即将创建的这个产品列表,我只需要每个产品一张预览图片。
正如最初所述,我的目标是获取所有产品的列表。那么让我们从简单的开始:
SELECT *
FROM product
现在我也想在产品页面显示一张预览图,所以需要一点加入:
SELECT `p`.*,
`pi`.`file` `previewImage`
FROM `product` `p`
LEFT JOIN `productImage` `pi` ON (`pi`.`productId` = `p`.`id`)
GROUP BY `p`.`id`
到目前为止一切顺利,这为我提供了每个产品一张预览图像以显示在产品列表中。还差一步:我要每个产品优先级最高的预览图作为预览图。所以我尝试使用子查询以所需的优先顺序获取产品图片:
SELECT `p`.*,
`pi`.`file` `previewImage`
FROM `product` `p`
LEFT JOIN (
SELECT *
FROM `productImage`
ORDER BY `priority` DESC
) `pi` ON (`pi`.`productId` = `p`.`id`)
GROUP BY `p`.`id`
但出于某种原因,这并没有(可靠地)为我提供每个产品具有最高优先级的产品图像。这是为什么?我认为 GROUP BY
选择了错误的 productImage 条目来保留,但为什么呢?它不应该选择第一个吗,由于子查询应该是优先级最高的那个?
您的分组依据是部分分组依据。您按 product.id
分组,因此 MySQL 将按产品对结果进行分组,但在每个组中,可以自由 return 来自 productimage
table 的任何行。要获得确定性结果,table 中的每一列都需要包含在聚合函数(MIN、MAX 等)中,但这不会为您提供具有最高优先级的图像。
也就是说,如果您只想要 productimage
table 中的一列,您可以在 select:
select product.*, (
select file
from productimage
where productimage.productid = product.id
order by priority desc
limit 1 -- this is the important bit
) as productimage_file
from product