web-dev-qa-db-ja.com

SELECT LEFT JOINが、一致したすべての値がnullであるレコードのみ

2つのテーブルnamelocationがあるとします

name    |   location_id
'A'     |   NULL
'A'     |   NULL
'B'     |   NULL
'B'     |   2
'C'     |   3
'C'     |   4

location_id |   location_name
1   |   Australia
2   |   Belgium
3   |   Croatia
4   |   Chile
5   |   Denmark
CREATE TABLE location (
    location_id INT PRIMARY KEY,
    location_name VARCHAR(64)
);

INSERT INTO location VALUES
    (1, 'Australia'),
    (2, 'Belgium'),
    (3, 'Croatia'),
    (4, 'Chile'),
    (5, 'Denmark');

CREATE TABLE name (
    id INT PRIMARY KEY,
    fname VARCHAR(64),
    location_id INT,
    FOREIGN KEY (location_id) REFERENCES Location(location_id)
);

INSERT INTO name VALUES
    (1, 'A', NULL),
    (2, 'A', NULL),
    (3 ,'B', NULL),
    (4 ,'B', 2),
    (5 ,'C', 3),
    (6 ,'C', 4);

一致するすべての値がnullであるレコードのみを選択します。 Alocation_idと一致しないため表示されますが、B2またはBelgiumと一致するため表示されません。

SELECT fname, location_name
FROM name n LEFT JOIN location l
USING (location_id)
WHERE location_name IS NULL

クエリ結果:

name    |   location_name
'A'     |   NULL
'A'     |   NULL
'B'     |   NULL

望ましい結果:

name    |   location_name
'A'     |   NULL
'A'     |   NULL

誰かが私にガイドして、望ましい結果が得られるWHEREステートメントを書く方法を教えてください。ありがとう!

1
TacticalBacon

NULL値を持つ行だけが必要な場合は、これを使用できます。

SELECT fname,location_id
FROM name WHERE fname NOT IN 
(SELECT fname FROM name WHERE location_id IS NOT NULL)

コードの最後の行は、NULLとは異なる値を持つ行を削除します

1
Topup

正確にはわかりませんが、COUNT(col)はnullをカウントしません。

SELECT fname
FROM name
GROUP BY fname
HAVING COUNT(location_id) = 0

名前を指定して自己結合を実行すると、カーディナリティが返されます。

SELECT a.fname, a.location_id
FROM name a
JOIN (
    SELECT fname
    FROM name
    GROUP BY fname
    HAVING COUNT(location_id) = 0
) as b
    USING (fname)

それは失敗することが保証されているので、私は本当に場所と結合する点を見ていませんが、

SELECT a.fname, c.location_name
FROM name a
JOIN (
    SELECT fname
    FROM name
    GROUP BY fname
    HAVING COUNT(location_id) = 0
) as b
    USING (fname)
LEFT JOIN location c
    USING (location_id);
0
Lennart