Sql server 如果满足条件,则SQL Server左联接

Sql server 如果满足条件,则SQL Server左联接,sql-server,Sql Server,我的查询有问题。只有当条件为真时,我才能做左外连接。如果条件为false,则执行另一个左外部联接 我尝试过这个,但没有成功: 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

我的查询有问题。只有当条件为真时,我才能做左外连接。如果条件为false,则执行另一个左外部联接

我尝试过这个,但没有成功:

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

如何解决此问题?

您可以尝试下面的查询

第一种方法:

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在运行时生成查询。

您可以查看动态SQL。其主要思想是在运行时构造和编译SQL语句

你可以从这里开始:


或者在这里:

您应该尝试左键连接这两个选项,但在select中,根据用例选择您想要的内容

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

考虑到您希望显示所有列(
*
),您可以通过检查
工作来有条件地对两个表进行联接。键入
作为联接条件:

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)

如果需要重复使用同一个select,可以创建一个表值函数来包装它,这样就不必每次都编写代码。我将使用表格示例来显示另一个备选方案,使用
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)

你好谢谢你的回复。这项工作。但我只需要使用条件进行一次联接,@databasecoder即使第一个联接为true,也会进行第二次左联接,即work.type=1请不要将
与(nolock)
一起使用-这可能是解决此问题的最佳模式。如果可以的话,我会试试。谢谢。删除了我的答案,结果为空,这是一个更好的解决方案。
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)
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