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