How to do intersection on a composition table

不羁岁月 提交于 2019-12-13 03:48:50

问题


I have a simple SQL relational model with a many to many relation. Here is the composition table

 ___________________________
| object1_id  | object2_id  |
|---------------------------|

I would like to know all the object1 that are common to a set of object2. My basic feeling is to do a request like this

SELECT c.object1_id FROM composition c WHERE c.object2_id = <given_id_1>
INTERSECT 
SELECT c.object1_id FROM composition c WHERE c.object2_id = <given_id_2>

And if I have N object2 in the set, I'll do N INTERSECT

SELECT c.object1_id FROM composition c WHERE c.object2_id = <given_id_1>
INTERSECT 
SELECT c.object1_id FROM composition c WHERE c.object2_id = <given_id_2>
...
INTERSECT 
SELECT c.object1_id FROM composition c WHERE c.object2_id = <given_id_N>

However, it doesn't look very optimized. Can you help me ? I am not really a SQL expert. I think I could use a JOIN to do that.

Sample

 ___________________________
| object1_id  | object2_id  |
|---------------------------|
|         10  |           1 |
|         11  |           1 |
|         10  |           2 |
|         12  |           2 |
|         10  |           3 |
|         11  |           3 |
|         13  |           3 |

Example

  • { object2_id set } => { expected object1_id }
  • { 1, 2 } => { 10 }
  • { 1, 3 } => { 10, 11 }
  • { 1, 2, 3 } => { 10 }

回答1:


In terms of performance your query looks OK. Have you measured it to see if there really is a problem?

If (object1_id, object2_id) is unique then you can write the query more concisely as follows:

SELECT object1_id
FROM composition
WHERE object2_id IN (id1, id2, ..., id6)
GROUP BY object1_id
HAVING COUNT(*) = 6

Note that the 6 is the number of provided IDs. This should be changed if a different number of IDs is provided. You would have to measure the actual performance on your dadta to see if this gives any speed increase.

If you can't assume uniqueness then this should work:

SELECT object1_id
FROM composition
WHERE object2_id IN (id1, id2, ..., id6)
GROUP BY object1_id
HAVING COUNT(DISTINCT object2_id) = 6

The most important thing though is to make sure you have appropriate indexes on your table! This is far more important than whether you write one query or the other.




回答2:


I believe this should work. It will find all composition 1's that also have a composition 2 that matches. Unless I am misunderstanding what you are looking for. If so, could you provide some sample data?

SELECT c1.object_id 
FROM Composition AS c1
WHERE EXISTS 
    (
        SELECT 1
        FROM Composition c2
        WHERE c2.object2_id = c1.object1_id
        --Add an AND to only look for a certain set of c2's
        --AND c2.object2_id IN (SET of object2id's)
    )



回答3:


I think this is a relational division question.

Analogy: find the supplier who supplies all parts.

object2_id is part_id

object1_id is supplier_id

The query is,

Find supplier_id values for suppliers who supply all parts in the set of part_id values { 1, 2, 3 }.

This is usually qualified with,

...suppliers who supply at least one part and...

otherwise all suppliers would supply the empty set of parts.



来源:https://stackoverflow.com/questions/9775593/how-to-do-intersection-on-a-composition-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!