这应该非常接近:
SELECT
tag.id,
tag.name,
tag_group.cnt,
tag_group.max_karma,
image.id,
imagefile.filename
/* ... */
FROM
tag
/* join against a list of max karma values (per tag) */
INNER JOIN (
SELECT MAX(image.karma) AS max_karma, COUNT(image.*) cnt, tag_map.tag_id
FROM image
INNER JOIN tag_map ON tag_map.image_id = image.id
GROUP BY tag_map.tag_id
) AS tag_group ON tag_group.tag_id = tag.id
/* join against a list of image ids (per max karma value and tag) */
INNER JOIN (
SELECT MAX(image.id) id, tag_map.tag_id, image.karma
FROM image
INNER JOIN tag_map ON tag_map.image_id = image.id
GROUP BY tag_map.tag_id, image.karma /* collapse >1 imgs with same karma */
) AS pop_img ON pop_img.tag_id = tag.id AND pop_img.karma = tag_group.max_karma
/* join against actual base data (per popular image id) */
INNER JOIN
image ON image.id = pop_img.id
INNER JOIN
imagefile ON imagefile.image_id = pop_img.id AND imagefile.type = 'smallthumb'
基本上,这是
the ever-recurring "max-per-group" problem
:如何选择与组的最大/最小值相对应的记录?
一般的答案都是这样的:选择你的小组(
tag_id, MAX(image.karma)
)然后根据这些特性连接基础数据。可能有特定于DBMS的专有扩展采用不同的方法,例如使用
ROW_NUMBER()
/
PARTITION BY
. 但是,这些都不是非常便携的,在使用不支持它们的DBMS时可能会让您抓耳挠腮。