2012-02-01 128 views
2

我有這樣一個表:SQL子查詢與複雜的標準

TransId. LayerNo. AccountId. 
100.  1.  2.   
100.  2.  3.   
120.  1.  5.   
120.  2.  6.  
120.  3.  12.  
70.  1.  2. 

我想找到TRANSID(s)的結合: (LayerNo = 1和(帳戶= 2或5)) 和 (LayerNo = 2和(accountId = 3或6))

而結果集是行號1,2,3,4。 我如何寫查詢來獲得結果? 我的數據庫是SQL Server 2008 R2的 預先感謝 尼瑪

+1

是否有和以上的?無論其他值如何,都無法使LayerNo = 1和LayerNo = 2。 – 2012-02-01 21:28:44

+0

LayerNo如何成爲1和2?你的意思是「還是LayerNo = 2」? – 2012-02-01 21:29:58

+0

基於期望的結果集,他正在尋找既滿足**條件又滿足**條件的TransID,因此對LayerNo 1 AND 2與1 OR 2的混淆 – nybbler 2012-02-01 21:38:34

回答

5
SELECT TransId 
FROM your_table 
WHERE (layerno = 1 
     AND accountid IN (2, 5)) 
INTERSECT 
SELECT TransId 
FROM your_table 
WHERE (layerno = 2 
     AND accountid IN (3, 6)) 
+0

+1我總是忘記INTERSECT。非常好。 – 2012-02-01 21:49:13

+0

+1 INTERSECT的良好通話。 – nybbler 2012-02-01 22:09:45

+0

是的,這是greate :) – nima 2012-02-02 06:58:36

3

一種方法是確保每個TRANSID必須有兩個記錄滿足你列出的條件。

SELECT * FROM 
TABLE 
WHERE TransID IN( 
    SELECT TransId 
    FROM table 
    WHERE (layerno = 1 
      AND accountid IN (2, 5) ) 
      OR (layerno = 2 
       AND accountid IN(3, 6) ) 
    GROUP BY 
     TransId 
    HAVING Count(*) = 2 
    ) 

然而,這可能是一個問題,如果你可以有multple記錄,其中layerno = 1,所以,你可以使用自聯接來代替,以保證標準。

SELECT DISTINCT a.transid 
FROM table a 
     INNER JOIN table b 
     ON a.transid = b.transid 
     INNER JOIN table c 
     ON a.transid = c.transid 
WHERE b.layerno = 1 
     AND accountid IN (2, 5) 
     AND c.layerno = 2 
     AND accountid IN (3, 6) 

也就是說Martin's INTERSECT做法可能是最好的

+1

這將包括結果集中的第6行,即不想要 – nybbler 2012-02-01 21:39:06

+0

@nybbler。感謝您指出了這一點。固定 – 2012-02-01 21:42:33

+0

你的答案也做這項工作,但正如你所說康萊德的解決方案更容易和更多我有層面檢查,更多的聯合應該介入,我認爲這將是一個性能問題。我對嗎? – nima 2012-02-02 07:12:54

-1
SELECT * 
    FROM table 
WHERE (LayerNo = 1 AND (AccountID = 2 OR AccountID = 5)) 
    OR (LayerNo = 2 AND (AccountID = 3 OR AccountID = 6)) 
+0

他只需要有符合兩個條件的行的transids。這隻會檢查單行。 – JNK 2012-02-01 21:50:21

0

你的意思是:

SELECT 
    TransId, 
    LayerNo, 
    AccountId 
FROM Table 
WHERE (LayerNo = 1 AND AccountId IN (2, 5)) OR 
     (LayerNo = 2 AND AccountId IN (3, 7)) 
0
create table #temp 

(rowId Int Identity(1,1), transId int) 

INSERT INTO #temp(transId) 
select TransId 
from TableName 
where (layerNo = 1 and accountID IN (2, 5)) 
OR (layerNo = 2 and accountId IN (3, 6)) 
select * from #temp 
0
SELECT 
    base.TransId, 
    base.LayerNo, 
    base.AccountId 
FROM TableX AS base 
    JOIN TableX AS a 
    ON a.TransId = base.TransId 
    AND a.LayerNo = 1 AND a.AccountId IN (2, 5) 
    JOIN TableX AS b 
    ON b.TransId = base.TransId 
    AND b.LayerNo = 2 AND b.AccountId IN (3, 7) 
WHERE (base.LayerNo = 1 AND base.AccountId IN (2, 5)) 
    OR (base.LayerNo = 2 AND base.AccountId IN (3, 7)) 
0

這個交點是空的。如果將LayerNo = 1和LayerNo = 2的值與相交,則它們的交集爲空,因爲這些事件是互斥的。我相信這個錯誤來自於最初陳述問題的方式。我可能是錯的,但謂詞應該是 (LayerNo = 1和(accountId = 2或5))OR(LayerNo = 2和(accountId = 3或6)) 用AND替換AND。如果謂詞正確表示,則相交是正確的,但始終爲空。