条件连接的最佳方式 - SQL Server

时间:2017-09-21 13:55:06

标签: sql sql-server

我有两个表,表A总是有数据,表B可以是空的。当我知道表B为空时,我想将@Filter参数设置为0并查看表A中的所有记录(然后忽略表B)。当我知道表B不为空时,我想将@Filter参数设置为1,以仅显示两个表之间的共同行(使用列X和Y)。

我从来没有找到一个明确的解决方案,我尝试了不同的方法,但我不喜欢这些:

  • exec @sqlString :潜在的sql注入/不是很可读的代码(恕我直言)
  • UNION :我的查询太大而无法复制
  • 在WHERE条件中使用:在某些情况下太慢

     DECLARE @Filter BIT = 0
    
     SELECT A.*
     FROM   A, B
     WHERE  @Filter = 0 OR (B.X = A.X AND B.Y = A.Y)
    

有没有人知道另一种方式?

3 个答案:

答案 0 :(得分:1)

从左连接开始到B,这样你就可以建立A-B关系了。

然后,在您的where子句中,测试您的过滤器 如果为0,则全部获取

OR

如果1 AND确保B.X字段不是NULL(因此存在)并且只返回两个表中的那些记录。

SELECT 
      A.* 
   FROM 
      A LEFT JOIN B 
           ON A.X = B.X AND A.Y = B.Y
   where
           @Filter = 0
      OR ( @Filter = 1 AND NOT ISNULL( B.X ))

答案 1 :(得分:0)

您可以使用IF声明

IF EXISTS (SELECT TOP 1 X FROM B) -- make sure something is there
  BEGIN
    -- if there is, do the join
    SELECT *
    FROM A
    INNER JOIN B ON B.X = A.X AND B.Y = A.Y
  END
ELSE
  BEGIN
    -- nothing in B, select everything from A
    SELECT *
    FROM A
  END

答案 2 :(得分:0)

我相信你正在寻找这样的东西:

SELECT A.* 
FROM
   A  
WHERE 
   EXISTS(SELECT 1 from B WHERE A.X = B.X AND A.Y = B.Y)
   OR NOT EXISTS(SELECT 1 FROM B)

如果表B为空,它将显示表A中的所有记录,当表B不为空时,它将仅显示来自表A的常见记录

完整代码:

declare  @A table
(
    x int,
    y int 
)
declare  @B table
(
    x int,
    y int 
)

insert into @A
values(1,1),
(1,2)

--Uncomment code below to insert data in table B
--insert into @B
--values(1,1) --,
--(1,2)

SELECT A.* 
FROM
   @A A 
WHERE 
   EXISTS(SELECT 1 from @B B WHERE A.X = B.X AND A.Y = B.Y)
   OR NOT EXISTS(SELECT 1 FROM @B)