我遇到了自己的MySQL查询技能限制,所以我希望一些SQL大师可以帮助解决这个问题。情况如下:
我有可以标记的图像。正如您所料,这存储在三个表中:
我有一个SQL查询,它根据标签ID计算相关标签。该查询基本上使用该标签检查用于图像的图像的其他标签。例如:
Image1标记为“熊”
Image2标记为“熊”和“加拿大”
如果我在查询中抛出“熊”(或其标签ID),它将返回“加拿大”。这很好用。这是查询:
SELECT tag.name, tag.id, COUNT(tag_map.id) as cnt
FROM tag_map,tag
WHERE tag_map.tag_id = tag.id AND tag.id != '185' AND tag_map.image_id IN
(SELECT tag_map.image_id FROM tag_map INNER JOIN tag ON tag_map.tag_id = tag.id WHERE tag.id = '185')
GROUP BY tag_map.id LIMIT 0,100
我坚持的部分是计数。对于返回的每个相关标签,我想知道该标签中有多少图像。目前它总是返回1,即使有例如3.我已经尝试计算不同的列都导致相同的输出,所以我想我的想法有一个缺陷。
答案 0 :(得分:2)
您的代码无法正常工作,因为您只选择“与选择的标签相关联的图像”,而不是图像,“与与选择标签关联的图像相关联的标签相关联”(我希望,我使用了正确的递归深度:))。
您可以使用子选择执行此操作:
SELECT tag.id, tag.name, COUNT(DISTINCT tag_map.image_id) as cnt
FROM tag_map, tag
WHERE tag_map.tag_id = tag.id
AND tag.id != 185
AND tag_map.tag_id IN (
SELECT sub1.tag_id FROM tag_map AS sub1 WHERE sub1.image_id IN (
SELECT sub2.image_id FROM tag_map AS sub2 WHERE sub2.tag_id = 185
)
)
GROUP BY tag.id, tag.name;
答案 1 :(得分:1)
有些值得深思的话
id
tag_map表中的图像表和tablename_id
。他自己的每个人都有,但我发现如果一个id被命名为无处不在,那就容易多了。我会重命名标签中的id's&图像到tag_id& image_id分别。以下示例使用SQL Server。不应该很难将SQL语句调整为MySQL。
测试数据
DECLARE @tag TABLE (id INTEGER, tag VARCHAR(32))
DECLARE @image TABLE (id INTEGER, image VARCHAR(32))
DECLARE @tag_map TABLE (image_id INTEGER, tag_id INTEGER)
INSERT INTO @tag
SELECT 185, 'Bear'
UNION ALL SELECT 186, 'Canada'
INSERT INTO @image
SELECT 1, 'image1'
UNION ALL SELECT 2, 'image2'
INSERT INTO @tag_map
SELECT 1, 185
UNION ALL SELECT 2, 185
UNION ALL SELECT 2, 186
SQL声明
SELECT t.tag
, t.id
, cnt = (SELECT COUNT(*) FROM @tag_map WHERE tag_id = t.id)
FROM @tag_map m
INNER JOIN @tag t ON t.id = m.tag_id
INNER JOIN (
SELECT m.image_id
FROM @tag_map m
WHERE m.tag_id = 185
) i ON i.image_id = m.image_id
WHERE t.id <> 185