从表中检索所有数据,然后计算另一个中的结果数

时间:2012-08-06 20:03:32

标签: php mysql

我想知道是否可以只使用一个MySQL查询。

我正在制作的是标记系统。因此,我有两个表:

Tags, id | heading

Tagged, id | image_id | tag_id | timestamp | strength

一切正常,但现在我正在进入我向用户显示标签的阶段,并计划根据标签的使用次数对它们进行排序。

简而言之,我需要做以下事情的事情,

  1. 抓取显示的当前图片的所有标签,例如id = 34
  2. 计算标签的使用次数。
  3. 按照这些结果对标签列表进行排序,从高到低。
  4. 现在我已经尝试过查看连接,左连接等等,但这看起来非常庞大,我发现很难掌握它。

    如果有人能够轻松解释如何做到这一点,那就太棒了!

    修改

    我目前有这个

    SELECT tags.id, COUNT( tagged.id ) AS count
    FROM tags
    INNER JOIN tagged ON tags.id = tagged.tag_id
    WHERE tagged.image_id =  '1'
    GROUP BY tags.id
    ORDER BY count DESC 
    

    这只返回标签被标记到当前image_id的次数,我将如何制作它以便从所有图像中计算?

4 个答案:

答案 0 :(得分:1)

您可以使用GROUP BY将相同标签组合在一起,并使用COUNT()对其进行统计:

  SELECT tags.id  as id,
         COUNT(1) as cnt
    FROM tags INNER JOIN tagged
      ON tags.id = tagged.tag_id
GROUP BY tags.id
ORDER BY cnt DESC

这就是它的确切作用:

  • 连接将标记每个条目,并将其与相应的标记配对。
  • 然后我们按标签ID分组,这样我们每个id只能获得一个条目。
  • COUNT函数计算每组中的元素数量。
  • 我们最终按计数降序排序,将最受欢迎的标签放在最上面。

此外,如果您希望每个图像都能够使用多个标签进行标记,您需要将图像信息移动到自己的表格中,并创建一个仅将两者结合在一起的表格。

答案 1 :(得分:1)

您可以优化SQL查询以便为您完成工作:

SELECT tags.id, COUNT(id) AS count
FROM tags
INNER JOIN tagged ON tags.id = tagged.tag_id
WHERE tagged.image_id = 34;
GROUP BY tags.id

这将选择设置为在图像标识34上标记的每个标记,然后使用该标记获取图像总数的计数。 Visual explanation of JOINs

答案 2 :(得分:0)

您可能正处于一个中间表中,该表保存两个表之间的关系,通常称为“normalization”。

tag_image_table
=========

tag | image
===========
1 | 23
99| 23

表示与2个标签相关联的图像#23。

这使得选择与标签关联的所有图像以及与图像关联的所有标签变得更加容易。

答案 3 :(得分:0)

要获取标记的全局用法,您可能需要重新加入标记表,因为您在原始标记表上应用了where条件。试试这个:

SELECT 
    t2.id,
    COUNT(t3.tag_id) AS global_count,
    GROUP_CONCAT(t3.image_id) AS images_with_tag
FROM 
    tagged t1
    JOIN tags t2 ON t2.id = t1.tag_id
    LEFT JOIN tagged t3 ON t3.tag_id = t2.id
WHERE t1.image_id = 1
GROUP BY t2.id
ORDER BY global_count DESC