1

誰かがmySQLを学ぶための良い本も推薦できれば、それは素晴らしいことです:)。

私は2つのテーブル、タグ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

私がやろうとしているのは、「tags」から名前を選択し、「codes_tags」にそのtag_idがいくつあるかを選択し、その数で並べ替えることです。そのtag_idのcodes_tagsにレコードがない場合、「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行しか返していません。

私はここで何が間違っているのですか?ありがとう。

4

3 に答える 3

1

いくつかのダミー データを使用して MySQL でこれをテストしたところ、クエリは 4 行以上を返すようです。create table ステートメントを実行し、次のステートメントを入力しました。

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も含まれると思います。(nullまたは0の場合、欠落しているとカウントされます。それ以外の場合、クエリは正常に表示されます)。

編集:考え直して、私は左の参加を逃しました。つまり、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

リストにない項目から、 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
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 JOINをに変更LEFT OUTER JOIN

于 2009-09-01T05:15:06.820 に答える