[Moved] Help needed for SQL query
-
wrote on 6 Jul 2011, 03:14 last edited by
[EDIT: moved to brainstorm, as it's not Qt related, Volker]
I am not expert on database and meet a problem on SQL query, can anyone help to solve it?
Background:
Have 3 tables A(column a), B(column b), A_B(columns a, b). A stores data A1, A2, A3..., B stores B1, B2, B3, B4..., A_B stores the relationship of A and B such like {A1, B1}, {A1, B2}, {A2, B1}, {A2, B2}, {A2, B4}.Question:
How to use SQL to select A data that A related B data has some special ones like B1, B2 and does not have some ones like B4, B5.
The result of above should be A1, because A2 has B4.My solution is :
@SELECT DISTINCT a FROM A_B WHERE b in (B1, B2)
MINUS
SELECT DISTINCT a FROM A_B WHERE b in (B4) @But this query's performance is not good enough(twice query), does anyone know how to write a SQL with more efficiency?
-
wrote on 6 Jul 2011, 06:46 last edited by
How about SELECT DISTINCT a FROM A_B WHERE (b IN (B1, B2)) AND (b NOT IN (B4)) ?
-
wrote on 6 Jul 2011, 07:14 last edited by
[quote author="cincirin" date="1309934816"]How about SELECT DISTINCT a FROM A_B WHERE (b IN (B1, B2)) AND (b NOT IN (B4)) ?[/quote]
I don't think this would work, for data columns {A1, B1}, {A1, B4}, the return value will still A1..
-
wrote on 6 Jul 2011, 07:23 last edited by
I do not really see how this would work without a second select statement. However, I think that it might not even matter how the statement is built (either using MINUS, EXCEPT, NOT IN, NOT EXISTS or JOIN) as after leaving the query optimizer it will all look the same and it will be heavily DBMS-related which one performs best.
If you really strive for performance you will have to build different versions and profile them.
Be aware the MINUS is DBMS-specific and not portable, DISTINCT ... EXCEPT should be.
-
wrote on 6 Jul 2011, 07:34 last edited by
@Lukas Geyer,
I agree with you, and do you know how to find A which has both B1,B4? -
wrote on 6 Jul 2011, 07:48 last edited by
I still would go with a sub-select @ SELECT a FROM a_b WHERE b = 1 AND a IN (SELECT a FROM a_b WHERE b = 4) @ An intersection would be another possibility @ SELECT a FROM a_b WHERE b = 1 INTERSECT SELECT a FROM a_b WHERE b = 4 @
Performance is still up to the query optimizer and would require profiling to find the "best" (which is probably not the fastest) solution.
-
wrote on 6 Jul 2011, 08:10 last edited by
@Lukas Geyer,
Thanks for your solution, so if there would be more B to be included, there would be more "Select" needed? -
wrote on 6 Jul 2011, 08:20 last edited by
I think so.
-
wrote on 6 Jul 2011, 08:33 last edited by
Or something like this
@SELECT a FROM (SELECT a, COUNT(DISTINCT b) as c a_b WHERE b IN(1,4) GROUP BY a HAVING c=2)@ -
wrote on 6 Jul 2011, 08:57 last edited by
[quote author="loladiro" date="1309941231"]Or something like this
@SELECT a FROM (SELECT a, COUNT(DISTINCT b) as c a_b WHERE b IN(1,4) GROUP BY a HAVING c=2)@[/quote]Good, that's what I want.
4/10