1

A sqlite database has the two following tables:

 table1               table2
---------           ---------
 f1 | f2             e  |  f
---------           ---------
  0 | 1              0  |  1 
  2 | 3              0  |  2
  1 | 4              0  |  3
  2 | 1              1  |  4
  0 | 2              1  |  0
  3 | 0              1  |  3

Now I would like to select those pairs of elements (f1,f2) from table1 where both f1 and f2 are among those f in table2, to which e=0.

This can be achieved with

SELECT f1, f2 FROM table1
WHERE f1 IN (SELECT f FROM table2 WHERE e=0)
AND f2 IN (SELECT f FROM table2 WHERE e=0)

The result, as expected is

2   3
2   1

but there is a repetition in the query above, which I thought could be eliminated by making

SELECT f1, f2 FROM table1
WHERE f1, f2 IN (SELECT f FROM table2 WHERE e=0)

but this gives me a syntax error, and

SELECT f1, f2 FROM table1
WHERE f1 AND f2 IN (SELECT f FROM table2 WHERE e=0)

doesn't give anything.

Is there a way to get it without repetition?

(My motivation is that this is to be accessed from a python program where the constants constraining the query are passed as arguments. With the code I'm using, I have to make tuples twice as big, with second half equal to the first, and I guess this will be more prone to errors, specially when the query is a bit more complicated. It's working, but I'd like to improve... I'm not including any of that python code because I don't think it's really relevant, but I could do that too.)

forpas
  • 160,666
  • 10
  • 38
  • 76
amrsa
  • 215
  • 2
  • 9

1 Answers1

1

If the combination of f1, f2 is unique in table1, you can join the tables, GROUP BY f1, f2 and set the condition in the HAVING clause:

SELECT t1.f1, t1.f2 
FROM table1 t1 INNER JOIN table2 t2
ON t2.f IN (t1.f1, t1.f2)
WHERE t2.e = 0
GROUP BY t1.f1, t1.f2
HAVING COUNT(*) = 2

See the demo.

forpas
  • 160,666
  • 10
  • 38
  • 76
  • Does `HAVING COUNT(*) = 2` mean that it's only to get the first two results? – amrsa Mar 21 '21 at 12:22
  • Ok, this certainly work. I don't understand it, but that just means that I must study some functionalities better. My combinations `(f1,f2)` are not necessarily unique, but they were in the example I gave, my bad. So I'll accept this and then I'll try to com up with something or ask another question. Thanks! – amrsa Mar 21 '21 at 12:31
  • 1
    @amrsa `HAVING COUNT(*) = 2` means that both f1 and f2 have a match in table2 and not only 1 of them. – forpas Mar 21 '21 at 12:37
  • Unfortunately, if I add a row to table1 with `f1=2` and `f2=3` (a repetition), the result is only the other pair, `(2,1)`. I'll have to think about that, or ask again. Thanks again! – amrsa Mar 21 '21 at 12:41
  • 1
    @amrsa In this case check this: https://dbfiddle.uk/?rdbms=sqlite_3.27&fiddle=80204520ca4c42c6489874fe7aa68787 In terms of performance EXISTS is usually better. – forpas Mar 21 '21 at 12:42