多行上的MS SQL匹配表

时间:2016-07-04 12:07:19

标签: sql-server

我想基于多行加入两个表,但无法找到正确的方法。

表格如下所示:

表1

Id  Location    LocationNo  
 1         1             1  
 1         2             2  
 1         3             3
 2         1             1
 2         2             2
 3         2             1
 3         1             2
 3         3             3
 4         1             1
 4         2             2
 4         3             3
 4         4             4

表2

    Location    LocationNo  
           1             1  
           2             2  
           3             3

我想从table1获取与table2中的行完全匹配的Id。 我希望返回值应为Id 1。

我已经尝试了下面的查询,但结果不是预期的结果。

SELECT t.Id
FROM   table1 t1
WHERE  EXISTS (SELECT 1
               FROM   table2 t2
               WHERE  t1.LocationId = t2.LocationId
                      AND t1.LocationNo = t2.LocationNo) 

有什么建议吗?感谢。

编辑: 的表2

    Location    LocationNo  
           1             1  
           2             2  
           3             3
           5             4

对于这种情况,我希望结果为null

3 个答案:

答案 0 :(得分:2)

Select Distinct t1.Id  --< Use Distinct to return unique values only
From table1 t1
Inner Join table2 t2   --< Use Inner Join instead of "where exists"
  On t1.LocationId = t2.LocationId
 AND t1.LocationNo = t2.LocationNo

更新:事实证明它比这更有趣:我们在这里寻找所有行的完全匹配:

Select t1.Id
From table1 t1
Left Join table2 t2 --< Left Join to register NULLs from table2
  On t1.LocationId = t2.LocationId
 AND t1.LocationNo = t2.LocationNo
Group By t1.Id
Having  --< Number of records from each table equals the count of matching criteria rows
    Count(t1.LocationId) = (Select Count(*) From table2)
AND Count(t2.LocationId) = (Select Count(*) From table2)

测试的源数据:

With table1 As (
    Select * From (Values 
     (1, 1, 1), 
     (1, 2, 2), 
     (1, 3, 3),
     (2, 1, 1),
     (2, 2, 2),
     (3, 2, 1),
     (3, 1, 2),
     (3, 3, 3),
     (4, 1, 1),
     (4, 2, 2),
     (4, 3, 3),
     (4, 4, 4)
    ) V (Id, LocationId, LocationNo)
), table2 As (
    Select * From (Values 
        (1, 1), 
        (2, 2), 
        (3, 3)
    ) V (LocationId, LocationNo)
)

答案 1 :(得分:2)

利用Inner Join

select t1.Id -- or t2.id, depends which table you want the ID from
from table1 t1
inner join table2 t2 
on t1.LocationId = t2.LocationId 
and t1.LocationNo = t2.LocationNo

答案 2 :(得分:1)

我认为你正在寻找这个

IF EXISTS(SELECT 1
          FROM   (SELECT Count(1) cnt,
                         id
                  FROM   Table1 a
                  GROUP  BY id) a
                 JOIN (SELECT t1.Id,
                              Count(1) cnt
                       FROM   table1 t1
                              JOIN table2 t2
                                ON t1.[Location] = t2.[Location]
                                   AND t1.LocationNo = t2.LocationNo
                       GROUP  BY t1.Id
                       HAVING Count(1) = (SELECT Count(1)
                                          FROM   table2)) b
                   ON a.cnt = b.cnt
                      AND a.Id = b.id)
  WITH tot_count
       AS (SELECT Count(1) cnt,
                  id
           FROM   #Table1 a
           GROUP  BY id),
       sub_cnt
       AS (SELECT t1.Id,
                  Count(1) cnt
           FROM   table1 t1
                  JOIN table2 t2
                    ON t1.[Location] = t2.[Location]
                       AND t1.LocationNo = t2.LocationNo
           GROUP  BY t1.Id
           HAVING Count(1) = (SELECT Count(1)
                              FROM   table2))
  SELECT b.id
  FROM   tot_count a
         JOIN sub_cnt b
           ON a.cnt = b.cnt
              AND a.Id = b.id
ELSE
  SELECT NULL