2012-03-19 18 views
0

我有一個簡單的SQL關係模型,具有多對多的關係。下面是成分表如何在構圖表上交集

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

我想知道所有的object1是常見的一組object2。我的基本感覺就是做這樣的

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> 

請求,如果我有N個對象2中集,我會做ň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> 

但是,它看起來不是很優化。你可以幫我嗎 ?我不是一個真正的SQL專家。我想我可以使用JOIN來做到這一點。

樣品

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

  • {object2_id組} => {預期object1_id}
  • {1,2} => {10}
  • { 1,3} => {10,11}
  • {1,2,3} => {10}

回答

2

就性能而言,您的查詢看起來OK。你是否測量了一下,看看是否真的有問題?

如果(object1_id, object2_id)是獨一無二的,那麼你可以更簡潔寫出如下查詢:

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

注意,6是提供ID的數量。如果提供了不同數量的ID,則應該更改該值。你必須測量你的爸爸的實際表現,看看這是否會提高速度。

如果您不能承擔的唯一那麼這應該工作:

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

最重要的事情,雖然是要確保你有你的桌子上適當的索引!這是遠遠高於比你寫一個查詢還是其他更重要。

+0

謝謝你幫助我很多。你的查詢是真正優化我想做什麼的,因爲我的查詢複雜度是什麼O(N),現在是O(1)(因爲我將遠遠超過2個對象相交)。再次感謝您 – 2012-03-20 09:18:16

1

我相信這應該工作。它會找到所有合成1也有一個合成2匹配。除非我誤解你在找什麼。如果是這樣,你能提供一些樣本數據嗎?

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) 
    ) 
+0

我添加了一個示例和示例,我不認爲您的查詢適用於我的情況,我不需要object2_id == object1_id。 – 2012-03-20 09:07:17

0

我覺得這是一個relational division的問題。

Analogy:找到供應商零件的供應商。

object2_idpart_id

object1_idsupplier_id

的查詢,

查找supplier_id值誰在一組part_id{ 1, 2, 3 }的供應所有的零部件供應商。

這通常是合格的,

...誰提供至少一個組成部分,...供應商

否則所有供應商將提供空集的部分。

+0

請問這個人是否可以發表他們關係分裂的證據不能解決問題?被接受的答案在我看來就像一個經典的劃分模式,但是對於除數集合的基數的硬編碼值即不會縮放。謝謝;) – onedaywhen 2012-04-11 06:19:36

+0

正確的答案,但它通常不太受讚賞,在這個領域,如果你只是給這個概念命名並給出一個鏈接。也許這就是原因。 – 2012-04-11 19:08:03

+0

@ErwinSmout:恐怕你是對的! – onedaywhen 2012-04-12 07:32:48