Search code examples
sqlitenestedwhere-in

Nesting "WHERE IN" (or AND, OR statements) SQLite


I'd like to have a SELECT query that gets 8 specific combinations of user1 & user2 (and that combination of user2 & user1 is also worth having and not redundant). The "IN" statement seemed worthwhile.

Directly related questions. 1. Can "WHERE IN" statements be nested?

  1. If not, how might I most effectively/ most easily structure a query so that I might specify (for 4 pairs where user1 and user2 switch position - 8 combinations): (where user1 = billy AND user2 = sue) OR (where user1 = sue AND user2 =billy) OR (user1 = jack AND user2 = jill) OR (user1 = jill AND user2 = jack)...etc ?

[At this point it seems easier to run the query and grep out the pertinent info.]

Current thought:

sqlite3 -header -separator , some.db "SELECT DISTINCT programquality.time, simscores.user1, simscores.user2, simscores.simscore, programquality.gf, programquality.ga, programquality.pq FROM simscores LEFT JOIN programquality ON programquality.time = simscores.time AND programquality.username = simscores.user1 WHERE programquality.pq IS NOT NULL WHERE simscores.user1 IN ("abraham","billy","carl","dave","ethan","frank","george","harry") WHERE simscores.user2 IN ("abraham","billy","carl","dave","ethan","frank","george","harry");"

I've used this, but some non-relevant data is displayed.

sqlite3 -header -separator , some.db 'SELECT DISTINCT programquality.time, simscores.user1, simscores.user2, simscores.simscore, programquality.gf, programquality.ga, programquality.pq FROM simscores LEFT JOIN programquality ON programquality.time = simscores.time AND programquality.username = simscores.user1 WHERE (simscores.user1  = "billy" OR simscores.user1 = "suzy" OR simscores.user1 = "john") AND (simscores.user2  = "billy" OR simscores.user2 = "suzy" OR simscores.user2 = "john") AND programquality.pq IS NOT NULL AND programquality.time IS NOT NULL;'

Solution

  • A query can have only one WHERE clause, but that expression can combine multiple conditions with AND or OR:

    SELECT ...
    FROM ...
    WHERE programquality.pq IS NOT NULL AND
          simscores.user1 IN ('abraham', 'billy', ...) AND
          simscores.user2 IN ('abraham', 'billy', ...)
    

    However, these IN expressions do not allow you to match specific values for user1 and user2. You cannot avoid listing all combinations you want.

    However, you can simplify the expression somewhat by check the combined names for valid combinations:

    ... WHERE ... AND
              simscores.user1 || '+' || simscores.user2
               IN ('billy+sue', 'sue+billy',
                   'jack+jill', 'jill+jack',
                   ...)