3

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

我正在做的是一个标签系统。因此,我有两个表:

Tags, id | heading

Tagged, id | image_id | tag_id | timestamp | strength

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

所以简而言之,我需要一些可以执行以下操作的东西,

  1. 获取当前显示的图像的所有标签,例如id = 34.
  2. 计算标签被使用了多少次。
  3. 按这些结果排序标签列表,从高到低。

现在我已经尝试研究连接、左连接等,但是这一切看起来都非常压倒性,我发现很难掌握它。

如果有人可以轻松地解释如何做到这一点,那就太好了!

编辑

我目前有这个

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

4 回答 4

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函数计算每组中有多少元素。
  • 我们最终按数量降序排列,将最受欢迎的标签放在最前面。

此外,如果您希望每张图像都可以使用多个标签进行标记,您需要将图像信息移动到其自己的表格中,并创建一个单独将两者链接在一起的表格。

于 2012-08-06T20:08:34.787 回答
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

这将选择设置为在图像 id 上标记的每个标签,34然后获取使用该标签的图像总数。JOIN 的可视化解释

于 2012-08-06T20:14:09.887 回答
0

您可能处于应该拥有一个包含两个表之间关系的中间表的地步,通常称为“规范化”。

tag_image_table
=========

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

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

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

于 2012-08-06T20:10:51.527 回答
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 
于 2012-08-06T22:18:10.420 回答