需要一些MySQL子查询计数的帮助

时间:2010-03-19 09:49:03

标签: sql mysql subquery

我遇到了自己的MySQL查询技能限制,所以我希望一些SQL大师可以帮助解决这个问题。情况如下:

我有可以标记的图像。正如您所料,这存储在三个表中:

  • 图像
  • 标签
  • Tag_map(将图片映射到标签)

我有一个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.我已经尝试计算不同的列都导致相同的输出,所以我想我的想法有一个缺陷。

2 个答案:

答案 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分别。
  • 看来你的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
相关问题