具有复杂条件的SQL子查询

时间:2012-02-01 21:23:44

标签: sql sql-server tsql sql-server-2008-r2

我有一张这样的表:

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和(accountId = 2或5)) 和 (LayerNo = 2和(accountId = 3或6))

结果集将是第1,2,3,4行。 我怎么能写查询来获得结果? 我的数据库是SQL server 2008 r2 提前致谢 尼马

7 个答案:

答案 0 :(得分: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 ) )  

答案 1 :(得分: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
    )

但是,如果你可以拥有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方法可能是最好的

答案 2 :(得分:0)

你的意思是:

SELECT 
   TransId,  
   LayerNo,  
   AccountId
FROM Table
WHERE (LayerNo = 1 AND AccountId IN (2, 5)) OR 
      (LayerNo = 2 AND AccountId IN (3, 7))

答案 3 :(得分: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

答案 4 :(得分: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))

答案 5 :(得分:0)

这个十字路口是空的。如果您获取LayerNo = 1和LayerNo = 2并且它们相交的值,则它们的交集为空,因为这些事件是互斥的。我认为这个错误来自最初陈述的问题。我可能错了,但谓词应该是 (LayerNo = 1和(accountId = 2或5))OR(LayerNo = 2和(accountId = 3或6)) 用OR替换AND。如果正确陈述了谓词,那么相交是正确的,但总是为空。

答案 6 :(得分:-1)

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