条件联接的最佳方式-SQL Server
我有两个表,表A总是有数据,表B可以是空的。当我知道表B为空时,我想将@Filter参数设置为0,并查看表A中的所有记录(然后忽略表B)。当我知道表B不是空的时,我想将@Filter参数设置为1,以仅显示两个表之间的公共行(使用列X和Y) 我从未找到明确的解决方案,我尝试了不同的方法,但没有一种是我喜欢的:条件联接的最佳方式-SQL Server,sql,sql-server,Sql,Sql Server,我有两个表,表A总是有数据,表B可以是空的。当我知道表B为空时,我想将@Filter参数设置为0,并查看表A中的所有记录(然后忽略表B)。当我知道表B不是空的时,我想将@Filter参数设置为1,以仅显示两个表之间的公共行(使用列X和Y) 我从未找到明确的解决方案,我尝试了不同的方法,但没有一种是我喜欢的: exec@sqlString:潜在的sql注入/不太可读的代码(IMHO) 联合:我的查询太大,无法复制 或在WHERE条件下:在某些情况下速度太慢 DECLARE @Filter BI
- exec@sqlString:潜在的sql注入/不太可读的代码(IMHO)
- 联合:我的查询太大,无法复制
- 或在WHERE条件下:在某些情况下速度太慢
DECLARE @Filter BIT = 0 SELECT A.* FROM A, B WHERE @Filter = 0 OR (B.X = A.X AND B.Y = A.Y)
有人知道另一种方法吗?从左连接到B开始,这样您就可以始终建立a-B关系 然后,在where子句中测试过滤器。
如果为0,则获取所有 或 如果为1,请确保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 ))
您可以使用
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
我相信你正在寻找这样的东西:
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)
左键连接什么?您有一个所谓的“全包查询”。这些在搜索中非常常见。他们肯定会有挑战性。盖尔·肖(Gail Shaw)在这个话题上有一篇很棒的文章。这是来自Erland Sommarskog的另一个例子,这可能会导致一些相当困难的性能问题。我不会复制我的选择,sorry@SeanLange没错,但考虑到我们对这些表的性质了解很少,OP已经使用UNION、WHERE和动态SQL打折了。这只是另一种选择(虽然不是我喜欢的)。不幸的是,这会减慢我的查询速度