Reputation: 337
CREATE TABLE my_table (
id INTEGER PRIMARY KEY,
key BOOLEAN NOT NULL
);
INSERT INTO my_table VALUES (10, true);
INSERT INTO my_table VALUES (11, true);
INSERT INTO my_table VALUES (12, true);
INSERT INTO my_table VALUES (20, false);
INSERT INTO my_table VALUES (21, false);
I wanted only values with id
equal to 11 or 12:
SELECT my_table_1.id,
my_table_1.key,
my_table_2.id,
my_table_2.key
FROM my_table AS my_table_1
INNER JOIN my_table AS my_table_2
ON my_table_1.id < my_table_2.id
AND my_table_1.key = my_table_2.key
AND my_table_1.id IN (11, 12)
Instead of the full result:
my_table_1.id | my_table_1.key | my_table_2.id | my_table_2.key |
---|---|---|---|
10 | t | 11 | t |
10 | t | 12 | t |
11 | t | 12 | t |
I got a wrong partial result:
my_table_1.id | my_table_1.key | my_table_2.id | my_table_2.key |
---|---|---|---|
11 | t | 12 | t |
I figured out how to get the full result with double IN
:
SELECT my_table_1.id,
my_table_1.key,
my_table_2.id,
my_table_2.key
FROM my_table AS my_table_1
INNER JOIN my_table AS my_table_2
ON my_table_1.id < my_table_2.id
AND my_table_1.key = my_table_2.key
AND (my_table_1.id IN (11, 12) OR my_table_2.id IN (11, 12))
Which gives me the correct result.
Another example with id IN (21)
:
SELECT my_table_1.id,
my_table_1.key,
my_table_2.id,
my_table_2.key
FROM my_table AS my_table_1
INNER JOIN my_table AS my_table_2
ON my_table_1.id < my_table_2.id
AND my_table_1.key = my_table_2.key
AND (my_table_1.id IN (21) OR my_table_2.id IN (21))
This also gives the correct result:
my_table_1.id | my_table_1.key | my_table_2.id | my_table_2.key |
---|---|---|---|
20 | f | 21 | f |
Without the second IN
, I would have got an empty result.
How can I improve this query?
I don't like using the IN
twice.
On the small amount data there's no problem. A problem appears on the real data, when e.g. 10000 ids is queried, and instead of one monstrous list of ids, there are two monstrous lists of ids.
Upvotes: 0
Views: 120
Reputation: 77
For Reduce multiple list if Ids Can use CTE like this
WITH IDs AS (
SELECT id FROM my_table WHERE id IN (11, 12)
)
SELECT my_table_1.id,
my_table_1.key,
my_table_2.id,
my_table_2.key
FROM my_table AS my_table_1
INNER JOIN my_table AS my_table_2
ON my_table_1.id < my_table_2.id
AND my_table_1.key = my_table_2.key
AND (my_table_1.id IN (SELECT id FROM IDs)
OR my_table_2.id IN (SELECT id FROM IDs))
ORDER BY my_table_2.id
Upvotes: 1