【发布时间】:2013-06-11 21:15:53
【问题描述】:
如果不满足条件,我正在尝试“短路”INNER JOIN。
我尝试了什么:
我发现如果在“ON”条件下,Left Join 前面有一个 False 子句,则 LEFT JOIN 失败。因此,我尝试用 LEFT OUTER JOIN 模拟 INNER JOIN,WHERE 子句得到如下执行计划:
DECLARE @a nvarchar(4) = 'All'
SELECT A.*
FROM [dbo].[your_table] A
LEFT JOIN [dbo].[your_table_2] B
ON @a <> 'All'
WHERE A.City_Code = CASE WHEN @a <> 'All'
THEN B.City_Code
ELSE A.City_Code END
这将使左连接“短路”并且永远不会发生。执行计划如下:
但是当我尝试通过将变量声明为“Al”而不是“All”来执行相同的语句时,我发现执行计划仍然相同。
我不知道 Join 是否发生在初始步骤中?
我想要什么:
我想知道上述方法是否正确?是否真的使 INNER JOIN 短路?
我基本上希望只有当变量不是“全部”时才在两个表之间进行内部连接,否则它不应该连接并继续进一步。我已经尝试过使用“OR”(短路)和“IN”(应用过滤器),但如果 IN 子句中有太多项目,性能会降低。
请帮助我并告诉我我的方法是否有任何错误。
样本数据:
只有当变量 'all' 时我才应该得到 INNER JOIN 结果
当变量 = 'All' 时,我应该得到表 A 即
注意:我已经简化了这个查询,因此看起来很简单的 if 语句就可以做到。实际上,我有 53 个参数需要检查和运行 JOINS。加上一个查询的结果集必须与另一个查询连接,即我在此之前还有其他几个 JOIN 条件:)
【问题讨论】:
-
不确定你想做什么,但从“TABLE SCAN”值我可以说你的表没有索引,因此连接可能很慢。我已经以任何一种方式加入了数百万条记录,它对我来说永远不会变慢,你在“on”中尝试做的事情实际上会导致表格的笛卡尔积。
-
@SumitGupta 我想做的是“短路”。如果变量是“所有”,则笛卡尔积甚至不应该发生,连接必须被忽略。
-
如果您向我们提供了示例数据和预期输出的示例,那么您会更容易理解您想要什么。
-
我已经包含了示例数据。这只是为了试用。实际项目数据更大,表格也很复杂。
-
据我了解,您正在搞乱您的需求和数据库结构。如果您在没有其他条件的情况下获得该变量,如果条件为假,它将为表 b 提供空值,如果条件为真,它会给出笛卡尔积,然后根据您的 where 条件进行过滤。更好地创建一个过程并在变量上放置 2 个带有条件的查询。因此,一个 queyr 将加入,而另一个则没有加入。
标签: sql sql-server tsql left-join inner-join