我有以下3个表格:
(PK =主键,FK =外键)
File ID (PK) File Name ...
------------ ---------
1 a.jpg ...
2 b.png ...
3 c.jpg ...
. .
. .
. .
Tag ID (PK) Tag Name ...
----------- ----------
1 Melbourne ...
2 April ...
3 2010 ...
. .
. .
. .
File ID (FK) Tag ID (FK)
------------ -----------
1 1
1 5
1 7
2 2
2 4
3 3
. .
. .
. .
在PHP中,我想获得所有标签的列表以及标签出现的次数(即具有此标签的文件数)。
这可能与一个MySQL查询有关吗?
答案 0 :(得分:5)
在您的代码ID上尝试GROUP BY。使用LEFT JOIN包含标签表中存在但未使用过的标签。
SELECT
Tag_Name,
COUNT(Files_Tags.Tag_ID) AS cnt
FROM Tags
LEFT JOIN Files_Tags
ON Tags.Tag_ID = Files_Tags.Tag_ID
GROUP BY Tags.Tag_ID
结果:
Melbourne 1 April 1 2010 1 ... ...
如果您希望按排序顺序返回行,可能还需要添加ORDER BY Tag_Name
或ORDER BY COUNT(*)
。
Daniel Vassello也提交了答案,但已将其删除。然而,他的答案很容易适应您的新要求。这是他的解决方案,修改为使用LEFT JOIN而不是INNER JOIN:
SELECT t.tag_id,
t.tag_name,
IFNULL(d.tag_count, 0) AS tag_count
FROM tags t
LEFT JOIN
(
SELECT tag_id, COUNT(*) tag_count
FROM files_tags
GROUP BY tag_id
) d ON d.tag_id = t.tag_id;
答案 1 :(得分:0)
你不应该使用太多的GROUP BY,ORDER BY和* JOIN,因为那些查询非常繁重,而且你不应该以你的代码为基础。
如果我是你,我会做多个简单的SELECT查询,并使用PHP算法将这些东西组合在一起。这样,你的DB就不会受到非常慢的查询的影响。
所以基本上,在你的具体问题中我会有超过1个查询。
我会先做一个
SELECT * FROM "tags_table".
在php中,我会创建一个foreach循环来计算“files_tags”表中每个标记的外观:
SELECT FILE_ID COUNT(*) FROM TAGS_TABLE WHERE TAG_ID = 'tag_uid'
它主要是伪代码,所以我不希望这些查询有效,但你会得到一般的想法。