不在子查询中没有返回正确的结果

时间:2017-12-12 06:01:35

标签: sql postgresql

我在PostgreSQL中运行此查询,以找出哪些状态在customer表中但在_customer表中缺失。我知道在这种情况下吉隆坡不见了(技术上不是一个州,我知道)。但是查询没有返回任何内容。

SELECT DISTINCT ("Billing Address State")
FROM customer
WHERE "Billing Address State" NOT IN (
    SELECT DISTINCT("Billing Address State")
    FROM _customer
);

其他查询:

SELECT DISTINCT ("Billing Address State")
FROM customer

NT
South Australia
Kuala Lumpur
Hertfordshire
NSW
Bangkok
West Java
Queensland
New South Wales
Western Australia
Stockholm
Victoria
WA
QLD
Gauteng
Australian Capital Territory
SA
Other
TAS
Northern Territory
VIC
Rhondda Cynon Taf
Tasmania
ACT
Îles du Vent
North Lanarkshire
Norfolk
Dublin

SELECT DISTINCT("Billing Address State")
FROM _customer;

NT
South Australia
Hertfordshire
NSW
Bangkok
West Java
Queensland
New South Wales
Western Australia
Stockholm
Victoria
ACT
Îles du Vent
WA
North Lanarkshire
Norfolk
Dublin
QLD
Gauteng
Australian Capital Territory
SA
Other
TAS
Northern Territory
VIC
Rhondda Cynon Taf
Tasmania

原始查询的补充:

SELECT DISTINCT ("Billing Address State")
FROM customer
WHERE "Billing Address State" IN (
    SELECT DISTINCT("Billing Address State")
    FROM _customer
);

返回吉隆坡以外的所有物品。换句话说,吉隆坡在_customer并且它不在同一时间。

3 个答案:

答案 0 :(得分:3)

当子查询返回空值时,

NOT IN变得棘手,正如@Thorsten Kettner已经解释过的那样。我总是建议切换到“null-safe”NOT EXISTS而不是:

SELECT DISTINCT "Billing Address State"
FROM customer c1
WHERE NOT EXISTS (
    SELECT *
    FROM _customer c2
    WHERE c2."Billing Address State" = c1."Billing Address State");

或者,在这种情况下,您只需使用EXCEPT

SELECT "Billing Address State"
FROM customer
EXCEPT
SELECT "Billing Address State"
FROM _customer

答案 1 :(得分:2)

NOT IN中的至少一个元素为null时,查询不返回任何内容。当某个值中的一个值是DBMS未知的值时,DBMS无法保证值不在列表中: - )

SELECT DISTINCT ("Billing Address State")
FROM customer
WHERE "Billing Address State" NOT IN (
    SELECT "Billing Address State"
    FROM _customer
    WHERE "Billing Address State" IS NOT NULL
);

答案 2 :(得分:0)

你也可以选择左联:

SELECT DISTINCT "Billing Address State"
FROM customer c1
LEFT JOIN _customer c2 ON c2."Billing Address State" = c1."Billing Address State"
WHERE c2.<whatever> IS NULL;