2011-06-14 51 views
8

我有一個看起來像這三個表:查找具有在許多完全匹配記錄,以一對多的關係

PROD

Prod_ID|Desc 
------------ 
P1|Foo1 
P2|Foo2 
P3|Foo3 
P4|Foo4 
... 

RAM

Ram_ID|Desc 
------------ 
R1|Bar1 
R2|Bar2 
R3|Bar3 
R4|Bar4 
... 

PROD_RAM

Prod_ID|Ram_ID 
------------ 
P1|R1 
P2|R2 
P3|R1 
P3|R2 
P3|R3 
P4|R3 
P5|R1 
P5|R2 
... 

之間PRODRAM有由PROD_RAM表中描述的許多一對多的關係。

給定一組Ram_ID(R1,R3)我想找到所有具有完全相同ONE在給定的RAM的ALLPROD

鑑於(R1,R3)應返回例如P1P4P5; P3不應退還,因爲有R1R3,但也R2

什麼來獲得最快的查詢都具有完全相同ONE給定RAM集的Ram_ID的ALLPROD

編輯:
PROD_RAM表可以包含關係比1-> 3更大,所以,對於計數 「硬編碼」 檢查= 1 OR = 2不是一個可行的解決方案。

+2

+1問清楚可理解的問題 – Stuti 2011-06-14 07:38:19

回答

2

你可以嘗試的速度另一種解決辦法是這樣的

;WITH CANDIDATES AS (
    SELECT pr1.Prod_ID 
      , pr2.Ram_ID 
    FROM PROD_RAM pr1 
      INNER JOIN PROD_RAM pr2 ON pr2.Prod_ID = pr1.Prod_ID 
    WHERE pr1.Ram_ID IN ('R1', 'R3') 
) 
SELECT * 
FROM CANDIDATES 
WHERE CANDIDATES.Prod_ID NOT IN (
      SELECT Prod_ID 
      FROM CANDIDATES 
      WHERE Ram_ID NOT IN ('R1', 'R3') 
     )   

,或者如果你不喜歡重複設置條件

;WITH SUBSET (Ram_ID) AS (
    SELECT 'R1' 
    UNION ALL SELECT 'R3' 
) 
, CANDIDATES AS (
    SELECT pr1.Prod_ID 
      , pr2.Ram_ID 
    FROM PROD_RAM pr1 
      INNER JOIN PROD_RAM pr2 ON pr2.Prod_ID = pr1.Prod_ID 
      INNER JOIN SUBSET s ON s.Ram_ID = pr1.Ram_ID  
) 
, EXCLUDES AS (
    SELECT Prod_ID 
    FROM CANDIDATES 
      LEFT OUTER JOIN SUBSET s ON s.Ram_ID = CANDIDATES.Ram_ID 
    WHERE s.Ram_ID IS NULL 
) 
SELECT * 
FROM CANDIDATES 
     LEFT OUTER JOIN EXCLUDES ON EXCLUDES.Prod_ID = CANDIDATES.Prod_ID 
WHERE EXCLUDES.Prod_ID IS NULL   
+0

測試了你的第一個解決方案a nd它的工作:) – systempuntoout 2011-06-14 09:12:03

+0

@systempuntoout - 現在你讓我想知道...和第二? – 2011-06-14 17:26:45

+0

還沒有嘗試過 – systempuntoout 2011-06-15 06:29:06

0
SELECT Prod_ID 
FROM 
    (SELECT Prod_ID 
     , COUNT(*) AS cntAll 
     , COUNT(CASE WHEN Ram_ID IN (1,3) 
         THEN 1 
         ELSE NULL 
        END 
       ) AS cntGood 
    FROM PROD_RAM 
    GROUP BY Prod_ID 
) AS grp 
WHERE cntAll = cntGood 
    AND (cntGood = 1 
    OR cntGood = 2    --- number of items in list (1,3) 
    ) 

完全不知道這是否是最快的方法。您必須嘗試使用​​不同的方法來編寫此查詢(使用JOIN s和NOT EXISTS)並測試速度。要做到這一點

0

一種方式是類似以下內容:

SELECT PROD.Prod_ID FROM PROD WHERE 

(SELECT COUNT(*) FROM PROD_RAM WHERE PROD_RAM.Prod_ID = PROD.Prod_ID) > 0 AND 

(SELECT COUNT(*) FROM PROD_RAM WHERE PROD_RAM.Prod_ID = PROD.Prod_ID AND PROD.Ram_ID <> 
IFNULL((SELECT TOP 1 Ram_ID FROM PROD_RAM WHERE PROD_RAM.Prod_ID = PROD.Prod_ID),0)) = 0 
相關問題