Hi I am working through example #7 from the sql zoo tutorial: SELECT within SELECT. In the following question
\"Find each country that belongs to a continent where all p
Show the table DECLARATION. It seems you use CONTINENT as the continent number. Then you should check it is marked with PRIMARY KEY and NOT NULL options. I realyl suspect you just forgot about very special meaning NULL has in SQL.
I make an example in 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;
Now let's try your requests and see if the 1st row, having CONTINENT IS NULL would be present anywhere:
SELECT continent, population FROM world
WHERE continent IN (
SELECT continent FROM world
WHERE population > 100)
CONTINENT POPULATION
2 200
4 110
and then
SELECT continent, population FROM world
WHERE continent NOT IN (
SELECT continent FROM world
WHERE population > 100)
CONTINENT POPULATION
1 10
3
By the logic of the request you suppose CONTINENT to be the row ID, then you should make it NOT-NULL and then there would not be the line, that is not seen by [NOT] IN condition.
Now, let re-phrase this into flat query:
SELECT continent, population FROM world
WHERE NOT (population > 100)
CONTINENT POPULATION
100
1 10
SELECT continent, population FROM world
WHERE population > 100
CONTINENT POPULATION
2 200
4 110
This time the missed row was the one having NULL for Population column.
Then FreshPrinceOfSO suggested using EXISTS clause. While potentially it may end with most slow (non-effective) query plan, it at least masks away the special meaning of NULL value in SQL.
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
100
1 10
3