Search code examples
sqlsqliterelational-division

Relational Division in SQL with SQLite


I'm trying to do a relational division on the following table (sorry for the Dutch phrasing) using this document and this question.

    voedsel_id  dier_id
    1005        1006
    1004        1006
    1005        1005
    1005        1004
    1004        1004
    1001        1003
    1001        1002
    1001        1001

Which let to the following query for what I want to do.

SELECT DISTINCT dier_id
FROM Dieren_voedsel AS X
WHERE NOT EXISTS(
    SELECT voedsel_id
    FROM Dieren_voedsel AS Y
    WHERE Y.dier_id = 1006 AND NOT EXISTS(
        SELECT voedsel_id
        FROM Dieren_voedsel AS Z
        WHERE X.voedsel_id = Z.voedsel_id AND Y.dier_id = Z.dier_id
    )
)
ORDER BY dier_id;

Which let to the following unexpected output.

dier_id
1004
1005
1006

I thought this division would output all the dier_id tuples that have exactly the same voedsel_id values as dier_id 1006. However, it includes dier_id 1005 which only has voedsel_id 1005 and dier_id 1006 has voedsel_id 1004 and 1005. I thought this would only return dier_id 1004 and 1006. Is there something I did wrong or do I not know how a relational division works?


Solution

  • In your innermost subquery, you got the references to X and Y wrong:

    SELECT DISTINCT dier_id
    FROM Dieren_voedsel AS X
    WHERE NOT EXISTS(
        SELECT *
        FROM Dieren_voedsel AS Y
        WHERE Y.dier_id = 1006
          AND NOT EXISTS(
            SELECT *
            FROM Dieren_voedsel AS Z
            WHERE Z.dier_id = X.dier_id
              AND Z.voedsel_id = Y.voedsel_id
        )
    )
    ORDER BY dier_id;