当且仅当某些条件为真时,我才想接受连接。 实施例 -
Table Employee
emp_no
emp_name
dept_no
Table Departnemt
dept_no
dept_name
declare @takeJoin BIT
select * from Employee e
if @takeJoin then
inner join Department d on e.dept_no=d.dept_no
如果@takeJoin为1,则只应进行内部联接,否则应按原样返回Employee中的所有记录。
我们可以写一般if if语句吗? 这只是一个示例,实际查询非常普遍
If @takeJoin =1
begin
end
else
begin
end
将不是一个合适的解决方案。
这样的事情可能吗?
答案 0 :(得分:4)
使用Left Join始终获取Employee记录并在WHERE子句中过滤掉它们。当@TakeJoin = 0时,我们在SELECT中使用DISTINCT来防止Employee和Department之间潜在的一对多关系(即使这可能是一对零/一)。只想展示一对多更复杂场景的技术。
SELECT DISTINCT e.emp_no,
e.emp_name,
e.dept_no,
CASE WHEN @TakeJoin = 1 THEN d.dept_no ELSE NULL END AS dept_dept_no
CASE WHEN @TakeJoin = 1 THEN d.dept_name ELSE NULL END AS dept_name
FROM Employee e
LEFT OUTER JOIN Department d ON e.dept_no = d.dept_no
--If @TakeJoin = 1/True, then make sure d.dept_no is not null to filter out Employee
--who have no department.
WHERE
--Mimic INNER JOIN on @TakeJoin = 1
((@TakeJoin = 1 AND d.dept_no IS NOT NULL) OR
--"Ignore" the Join and take all records
@TakeJoin = 0)
答案 1 :(得分:1)
最简单的方法是使用if
:
if @TakeJOin = 'Yes'
select *
from Employee e inner join
Department d
on e.dept_no = d.dept_no;
else
select *
from Employee e;
end;
使用SQL中的条件逻辑,这应该有效:
你可以这样做:
select e.*
from Employee e left join
Department d
on e.dept_no = d.dept_no and @TakeJoin = 'Yes'
where (@TakeJoin = 'Yes' and d.dept_no is not null) or
(@TakeJoin <> 'Yes')
请注意,您无法更改要返回的列数。如果你这样做:
select *
from Employee e left join
Department d
on e.dept_no = d.dept_no and @TakeJoin = 'Yes'
where (@TakeJoin = 'Yes' and d.dept_no is not null) or
(@TakeJoin <> 'Yes')
然后,您将获得Department
的所有列,但当NULL
为false时,它们将具有@TakeJoin
个值(无论您如何表示)。
答案 2 :(得分:1)
是的, 可以,但是您应该使用选项重新编译:
DECLARE @doJoin BIT = 0
SELECT *
FROM A
LEFT JOIN B on A.x = B.y and @doJoin = 1
option (recompile)
不重新编译选项,SQL Server将创建(并缓存)一个更通用的执行计划,该计划始终包括左联接,即使在您的特定情况下不需要它。使用此选项,您将在执行计划中看到对表A的聚集索引扫描,而没有对“ B”的任何访问。