SQL: find entries in 1:n relation that don't comply with condition spanning multiple rows
Posted
by milianw
on Stack Overflow
See other posts from Stack Overflow
or by milianw
Published on 2010-05-16T20:40:14Z
Indexed on
2010/05/16
20:50 UTC
Read the original article
Hit count: 178
I'm trying to optimize SQL queries in Akonadi and came across the following problem that is apparently not easy to solve with SQL, at least for me:
Assume the following table structure (should work in SQLite, PostgreSQL, MySQL):
CREATE TABLE a (
a_id INT PRIMARY KEY
);
INSERT INTO a (a_id) VALUES (1), (2), (3), (4);
CREATE TABLE b (
b_id INT PRIMARY KEY,
a_id INT,
name VARCHAR(255) NOT NULL
);
INSERT INTO b (b_id, a_id, name)
VALUES (1, 1, 'foo'), (2, 1, 'bar'), (3, 1, 'asdf'),
(4, 2, 'foo'), (5, 2, 'bar'), (6, 3, 'foo');
Now my problem is to find entries in a
that are missing name
entries in table b
. E.g. I need to make sure each entry in a
has at least the name
entries "foo"
and "bar"
in table b
. Hence the query should return something similar to:
a_id = 3 is missing name "bar"
a_id = 4 is missing name "foo" and "bar"
Since both tables are potentially huge in Akonadi, performance is of utmost importance.
One solution in MySQL would be:
SELECT a.a_id,
CONCAT('|', GROUP_CONCAT(name ORDER BY NAME ASC SEPARATOR '|'), '|') as names
FROM a
LEFT JOIN b USING( a_id )
GROUP BY a.a_id
HAVING names IS NULL OR names NOT LIKE '%|bar|foo|%';
I have yet to measure the performance tomorrow, but severly doubt it's any fast for tens of thousand of entries in a
and thrice as many in b
. Furthermore we want to support SQLite and PostgreSQL where to my knowledge the GROUP_CONCAT
function is not available.
Thanks, good night.
© Stack Overflow or respective owner