1

如果有人也可以推荐一本学习 mySQL 的好书,那就太好了:)。

我有两个表,tagscodes_tags

CREATE TABLE `tags` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `name` varchar(40) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=190 DEFAULT CHARSET=utf8


CREATE TABLE `codes_tags` (
 `code_id` int(11) unsigned NOT NULL,
 `tag_id` int(11) unsigned NOT NULL,
 KEY `sourcecode_id` (`code_id`),
 KEY `tag_id` (`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

我要做的是从'tags'中选择名称,以及'codes_tags'中有多少个tag_id,并按该计数排序。如果code_tags 中没有该tag_id 的记录,'count' 应该等于0 或NULL(最好是0)。

这是我到目前为止最接近的:

SELECT tags.name, COUNT( codes_tags.tag_id ) AS count
FROM tags
LEFT JOIN codes_tags ON tags.id = codes_tags.tag_id
GROUP BY tag_id
ORDER BY count DESC
LIMIT 0 , 30

它似乎做了我想要的,但是当它应该返回 30 时它只返回四行。

我在这里做错了什么?谢谢。

4

3 回答 3

1

我已经用一些虚拟数据在 MySQL 上对此进行了测试,查询似乎为我返回了超过 4 行。我运行了您的创建表语句,然后用以下语句填充它们:

insert into tags (name) values ('java'), ('mysql'), ('php'), ('ruby'), ('.net'), ('python');
insert into codes_tags (code_id, tag_id) values (1,194), (2,194), (3,194), (1,191), (2,191), (3,191), (4,191), (5,191), (1,192), (1,195), (1,193);

当我对该数据运行查询时,它返回 6 行。为了帮助进一步调试,您能否发布以下 2 个查询的结果:

select count(*) from tags;
select * from tags limit 10;

另外,为了确保您具有适当的数据完整性,您可以添加以下外键并查看它是否成功?

alter table codes_tags add foreign key codes_tags_tag_id_key(tag_id) references tags(id);
于 2009-09-01T05:20:38.430 回答
0

我认为,如果您在 SELECT 中将 COUNT(codes_tags.tag_id) 更改为 COUNT(*),也会包含 NULL。(如果您缺少空值或 0 计数。否则,查询看起来很好)。

编辑:再想一想,我错过了 LEFT JOIN。这意味着您需要所有标签,即使它们与 codes_tags 表中的某些内容无关。那是你要的吗?

我可能会做类似以下的事情:

SELECT tags.name, COUNT(*) AS count
FROM tags
INNER JOIN codes_tags ON tags.id = codes_tags.tag_id
GROUP BY tags.id
ORDER BY count(*) DESC

可以从不在列表中的项目推断出哪些标签也不包含在代码标签中。但是,如果您也想明确地这样做:

SELECT tags.name, COUNT(*) AS count
FROM tags
INNER JOIN codes_tags ON tags.id = codes_tags.tag_id
GROUP BY tags.id
UNION
SELECT tags.name, '0'
from tags
where tags.name not in 
   (SELECT tags.name
   FROM tags
   INNER JOIN codes_tags ON tags.id = codes_tags.tag_id)
ORDER BY count(*) DESC

(我目前无法访问 SQL 框,因此请对查询持保留态度;它们未经测试。)

于 2009-09-01T05:08:11.340 回答
0

更改LEFT JOINLEFT OUTER JOIN

于 2009-09-01T05:15:06.820 回答