If anyone could recommend a good book for learning mySQL as well, that would be great :).
I have two tables, tags, codes_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
What I am trying to do is select the name from ‘tags’, and how many of that tag_id there are in ‘codes_tags’, and order them by that count. If there is no records in codes_tags for that tag_id, ‘count’ should be equal to 0 or NULL (preferably 0).
This is the closest I have come so far:
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
It seems to do what I am wanting, however it is only returning four rows when it should return 30.
What am I doing wrong here?
Thanks.
I think if you change your COUNT(codes_tags.tag_id) to COUNT(*) in the SELECT, that NULLs will also be included. (If it’s nulls or 0 counts that you’re missing. Otherwise, the query looks fine).
EDIT: On second thought, I missed the LEFT JOIN. That would mean you want all of the tags even if they’re not related to something in the codes_tags table. Is that what you want?
I would probably do something like the following:
It can be inferred from the items not in the list which tags are not also included in codes_tags. However, if you wanted to explicitly do that as well:
(I don’t have access to a SQL box at the moment, so take the queries with a grain of salt; they’re untested.)