我的查询有问题。仅在条件为真时,我才需要进行左外部联接。如果条件为假,则执行另一个左外部联接。
我尝试过但没有成功:
select
*
from
works with(nolock)
if work.type = 1
begin
left outer join
users with(nolock) on users.id = work.owner
else
left outer join
groups with(nolock) on groups.id = work.owner
end
我该如何解决这个问题?
答案 0 :(得分:3)
您应该尝试将它们都左联接,但是在选择的内容中,根据用例采取您想要的东西。
SELECT
*,
CASE work.type WHEN '1' THEN 'a.owner' ELSE 'b.owner' END AS owner
FROM
blahblah
left join users on blahblah.user_id = users.id as a,
left join groups as blahblah.groups_id = groups.id as b
答案 1 :(得分:0)
您可以尝试以下查询。
第一种方法:
select
works.*, isnull(users.id, groups.id)
from
works with(nolock)
left outer join
users with(nolock) on users.id = works.owner and work.type = 1
left outer join
groups with(nolock) on groups.id = works.owner
第二种方法:
if exists (select 1 from works with (nolock) where works.type = 1)
select *
from works with(nolock)
left outer join users with(nolock) on users.id = works.owner
else
select *
from works with(nolock)
left outer join groups with(nolock) on groups.id = works.owner
第三种方法:使用动态SQL在运行时建立查询。
答案 2 :(得分:0)
考虑要显示所有列(*
),则可以通过检查work.type
作为联接条件,有条件地联接两个表:
select
*
from
works
left join users on
users.id = work.owner and
work.type = 1
left join groups on
groups.id = work.owner and
(work.type <> 1 OR work.type IS NULL)
works
表中的特定行只能具有type
的特定值,因此它将与users
或groups
联接,但不能同时联接。此解决方案的问题是显示的列,因为我们要同时针对两个表进行连接,所以现在您必须统一groups
和users
列。
您可以用一堆ISNULL
来做到这一点:
select
works.*,
Column1 = ISNULL(users.Column1, groups.Column1),
Column2 = ISNULL(users.Column2, groups.Column2)
from
works
left join users on
users.id = work.owner and
work.type = 1
left join groups on
groups.id = work.owner and
(work.type <> 1 OR work.type IS NULL)
如果需要重复使用同一选择,则可以创建一个表值函数将其包装起来,这样就不必每次都对其进行编码。我将使用表格示例显示另一个替代方法,即使用UNION ALL
。
CREATE FUNCTION dbo.GetWorkData (@owner INT) -- assuming its a INT
RETURNS TABLE
AS
RETURN
SELECT
-- Your wanted columns here
FROM
works AS W
INNER JOIN users AS U ON W.owner = U.owner
WHERE
W.owner = @owner AND
W.type = 1
UNION ALL
SELECT
-- Your wanted columns here (must be same data type and order of previous SELECT)
FROM
works AS W
INNER JOIN groups AS U ON W.owner = U.owner
WHERE
W.owner = @owner AND
(W.type <> 1 OR W.type IS NULL)
您可以将功能与APPLY
一起使用:
SELECT
D.*
FROM
works AS W
CROSS APPLY dbo.GetWorkData(W.owner) AS D -- User "OUTER APPLY" if you want works that have no users or groups
答案 3 :(得分:-1)
您可以研究动态SQL。主要思想是在运行时构造和编译SQL语句。
您可以从这里开始: Link 1 - MSSQL tips.