Return all rows where the entire list of a relatio

2019-09-13 04:42发布

问题:

With the following simple table structure:

Data
----------
id

Tag
----------
id

TaggedData
----------
id
tag_id
data_id

If I had a list of Tag ids, how would I fetch every row of Data where every row of Tag in my list has a relation to a row of Data matched and not a subset thereof?

Here's the query I have right now that doesn't work:

    SELECT
        Data.*

    FROM
        Data
    LEFT JOIN
        TaggedData ON (Data.id = TaggedData.data_id)
    LEFT JOIN
        Tag ON (Tag.id = TaggedData.tag_id)

    WHERE
        Tag.id IN ('1' , '2')

Specifically: This one isn't working because it will return any row of Data that is related to Tag 1 or 2. Not 1 and 2.

回答1:

This is called "relational division"

   SELECT 
        Data.ID  
    FROM 
        Data 
    INNER JOIN 
        TaggedData ON (Data.id = TaggedData.data_id) 
    INNER JOIN 
        Tag ON (Tag.id = TaggedData.tag_id) 
    WHERE 
        Tag.id IN ('1' , '2') 
    HAVING COUNT(DISTINCT tag.iD)=2