显示表声明。看来您使用 CONTINENT 作为大陆号。然后你应该检查它是否标有 PRIMARY KEY 和 NOT NULL 选项。我真的怀疑您只是忘记了 NULL 在 SQL 中的特殊含义。
我在 Firebird 2.5.1 SQL server 中做了一个例子。
CREATE TABLE WORLD (
CONTINENT INTEGER,
NAME VARCHAR(20),
POPULATION INTEGER
);
INSERT INTO WORLD (CONTINENT, NAME, POPULATION) VALUES (NULL, 'null-id', 100);
INSERT INTO WORLD (CONTINENT, NAME, POPULATION) VALUES (1, 'normal 1', 10);
INSERT INTO WORLD (CONTINENT, NAME, POPULATION) VALUES (2, 'normal 2', 200);
INSERT INTO WORLD (CONTINENT, NAME, POPULATION) VALUES (3, 'null-pop', NULL);
INSERT INTO WORLD (CONTINENT, NAME, POPULATION) VALUES (4, 'normal 4', 110);
COMMIT WORK;
现在让我们尝试您的请求,看看第一行是否存在 CONTINENT IS NULL :
SELECT continent, population FROM world
WHERE continent IN (
SELECT continent FROM world
WHERE population > 100)
CONTINENT POPULATION
2 200
4 110
接着
SELECT continent, population FROM world
WHERE continent NOT IN (
SELECT continent FROM world
WHERE population > 100)
CONTINENT POPULATION
1 10
3 <NULL>
根据请求的逻辑,您假设 CONTINENT 是行 ID,那么您应该将其设为 NOT-NULL,然后就不会出现 [NOT] IN 条件看不到的行。
现在,让我们将其重新表述为平面查询:
SELECT continent, population FROM world
WHERE NOT (population > 100)
CONTINENT POPULATION
<NULL> 100
1 10
SELECT continent, population FROM world
WHERE population > 100
CONTINENT POPULATION
2 200
4 110
这次错过的行是具有 NULL 的 Population 列。
然后FreshPrinceOfSO建议使用 EXISTS 子句。虽然它可能以最慢(无效)的查询计划结束,但它至少掩盖了 SQL 中 NULL 值的特殊含义。
SELECT continent, population FROM world w_ext
WHERE EXISTS (
SELECT continent FROM world w_int
WHERE (w_int.population > 100) and (w_int.continent = w_ext.continent)
)
CONTINENT POPULATION
2 200
4 110
SELECT continent, population FROM world w_ext
WHERE NOT EXISTS (
SELECT continent FROM world w_int
WHERE (w_int.population > 100) and (w_int.continent = w_ext.continent)
)
CONTINENT POPULATION
<NULL> 100
1 10
3 <NULL>