SQL Server оставил соединение, если условие выполнено - PullRequest
0 голосов
/ 10 июня 2019

У меня проблема с моим запросом. Я должен сделать левое внешнее соединение, только если условие истинно. Если условие ложно, выполните другое левое внешнее соединение.

Я пытался с этим, но не успешно:

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

Как мне решить эту проблему?

Ответы [ 4 ]

3 голосов
/ 10 июня 2019

вы должны попробовать присоединиться к ним слева, но внутри выбора выберите то, что вы хотите, в зависимости от варианта использования.

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
0 голосов
/ 10 июня 2019

Учитывая, что вы хотите отобразить все столбцы (*), вы можете условно объединить обе таблицы, проверив 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 s:

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
0 голосов
/ 10 июня 2019

Вы можете посмотреть на динамический SQL. Основная идея заключается в том, что оператор SQL создается и компилируется во время выполнения.

Вы можете начать здесь: Ссылка 1 - Советы по MSSQL.

или здесь: Ссылка 2 - официальная документация Microsoft.

0 голосов
/ 10 июня 2019

Вы можете попробовать запрос ниже.

Первый метод:

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 для построения запроса во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...