web-dev-qa-db-ja.com

2番目のテーブルが主キーに一致しない場合、1つのテーブルのレコードを選択し、別のテーブルのレコードは選択しない

2つのテーブルがあり、1つのテーブル(list)に表示され、2番目のテーブル(cardinal)には表示されない結果のみが必要です。 listテーブルの主キーはskuであり、テーブルには古いid列があります(これは現時点ではアプリケーションで実際には使用されていません)。 cardinalテーブルの主キーはidです。テーブルを結合する列はskuです。これらはテーブルです(関連フィールドのみ、ここに貼り付けなかった他のフィールドがあります):

mysql> describe list;
+-----------------+--------------+------+-----+---------+-------+
| Field           | Type         | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+-------+
| id              | int(11)      | NO   |     | NULL    |       |
| name            | varchar(63)  | YES  |     | NULL    |       |
| sku             | bigint(20)   | NO   | PRI | 0       |       |
+-----------------+--------------+------+-----+---------+-------+

mysql> describe cardinal;
+------------------+-------------+------+-----+---------+----------------+
| Field            | Type        | Null | Key | Default | Extra          |
+------------------+-------------+------+-----+---------+----------------+
| id               | int(11)     | NO   | PRI | NULL    | auto_increment |
| sku              | bigint(20)  | YES  | MUL | NULL    |                |
+------------------+-------------+------+-----+---------+----------------+

各テーブルのレコード数は次のとおりです。

mysql> SELECT count(*) FROM list;
+----------+
|  2677513 |
+----------+

mysql> SELECT count(*) FROM cardinal;
+----------+
|   970924 |
+----------+

cardinalテーブルのすべてのレコードにはsku列の有効なエントリがあり、これらの有効なエントリはすべてlistテーブルに存在します。 いくつかの重複が存在しますskuテーブルのcardinalに対して。

listテーブルに対応するエントリがないcardinalテーブルのすべてのレコードが必要です。ただし、私が試みているすべてのメソッドは、listテーブルのすべてのレコードを返すか、まったくレコードを返さない!

mysql> SELECT count(*) FROM list l LEFT JOIN cardinal c ON c.id=null;
+----------+
| count(*) |
+----------+
|  2677513 |
+----------+
1 row in set (0.49 sec)

mysql> SELECT count(*) FROM list l LEFT OUTER JOIN cardinal c ON l.sku=c.sku where c.id=null;
+----------+
| count(*) |
+----------+
|        0 |
+----------+

最初のクエリは、sku列で一致することを明らかに認識していません。しかし、2番目のものは動作するはずです ベースon他の回答私がしたことseenオンライン

約1700000-2000000行が返されることを期待しています。ただし、0またはテーブル全体ではありません。クエリをどのように表現すればよいですか?これは、Amazon RDSで実行されているMySQL 5.5.33です。

1
dotancohen

MySQL、実際、すべてのSQL製品は、

c.id=NULL

それは混乱を引き起こします。あなたは本当に意味します

c.id IS NULL

に変更する必要があります

SELECT count(*) FROM list l LEFT OUTER JOIN cardinal c ON l.sku=c.sku where c.id is null;

試してみる !!!

あなたの質問について

最初のクエリ

SELECT count(*) FROM list l LEFT JOIN cardinal c ON c.id=null;

カーディナルテーブルで何も一致しない自然な結合に似ているため、カウント2677513 正しい。

2番目のクエリ

SELECT count(*) FROM list l LEFT OUTER JOIN cardinal c ON l.sku=c.sku where c.id=null;

もう少し明示的ですが、c.id=nullは失敗するため、0がカウントされます。

3
RolandoMySQLDBA