我不是一个数据库专家,所以我需要一些关于我正在处理的查询的帮助。在我的照片社区项目中,我希望通过不仅显示标签名称和计数器(其中的图像数量)来丰富地可视化标签,我还想在标签内显示最流行图像的拇指(大多数业力)。
表格设置如下:
在我通常的试验和错误查询创作中,我走到了这一步:
SELECT * FROM
(SELECT tag.name, tag.id, COUNT(tag_map.tag_id) as cnt
FROM tag INNER JOIN tag_map ON (tag.id = tag_map.tag_id)
INNER JOIN image ON tag_map.image_id = image.id
INNER JOIN imagefile on image.id = imagefile.image_id
WHERE imagefile.type = 'smallthumb'
GROUP BY tag.name
ORDER BY cnt DESC)
as T1 WHERE cnt > 0 ORDER BY cnt DESC
[为了简单起见,内部查询的列子句被剪断]
这个查询给了我一些我需要的东西。外部查询确保仅返回至少有1个图像的标记。内部查询返回标签详细信息,例如其名称,计数(图像数)和拇指。另外,我可以根据需要对内部查询进行排序(大多数图像,按字母顺序,最近等)
到目前为止一切顺利。然而问题是这个查询与标签中最流行的图像(大多数业力)不匹配,它似乎总是采用标签中最新的一个。
如何确保最受欢迎的图片与标签匹配?
答案 0 :(得分:4)
您正在寻找'having'子句组,而不是嵌套选择!
SELECT tag.name, tag.id, COUNT(tag_map.tag_id) as cnt
FROM tag
INNER JOIN tag_map
ON (tag.id = tag_map.tag_id)
INNER JOIN image
ON tag_map.image_id = image.id
INNER JOIN imagefile
on image.id = imagefile.image_id
WHERE imagefile.type = 'smallthumb'
GROUP BY tag.name HAVING COUNT(tag_map.tag_id) > 0
ORDER BY cnt DESC
答案 1 :(得分:3)
这应该非常接近:
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时可能会让您感到头疼。