Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Несложный запрос  [new]
user89
Member

Откуда:
Сообщений: 2083
Есть главная таблица
idxName
1Offer 01

и две подчинённых
idxitemIDsubName
111sub 01
112sub 02

idxitemIDotName
121ot 01
122ot 02
123ot 03

Требуется получить такой результат:
idxNameitemIDsubName
1Offer 0111sub 01
1Offer 0112sub 02
1Offer 0121ot 01
1Offer 0122ot 02
1Offer 0123ot 03


Решается через union all
declare @main table (idx int, Name varchar(50))
insert @main values (1,'Offer 01')
declare @sub table(idx int, itemID int, subName varchar(50))
insert @sub values (1,11,'sub 01'), (1,12,'sub 02')
declare @ot table(idx int, itemID int, otName varchar(50))
insert @ot values (1,21,'ot 01'), (1,22,'ot 02'), (1,23,'ot 03')

select m.idx, m.Name, sub.itemID, subName
from @main m
left join @sub sub on m.idx = sub.idx
union all
select m.idx, m.Name, ot.itemID, otName
from @main m
left join @ot ot on m.idx = ot.idx

Так, чисто ради интереса, можно решить за один проход по таблице main без использования union all ?
5 мар 16, 13:11    [18900258]     Ответить | Цитировать Сообщить модератору
 Re: Несложный запрос  [new]
user89
Member

Откуда:
Сообщений: 2083
SQL 2008 R2
5 мар 16, 13:12    [18900259]     Ответить | Цитировать Сообщить модератору
 Re: Несложный запрос  [new]
Glory
Member

Откуда:
Сообщений: 104751
Так, чисто ради интереса, можно решить за один проход по таблице main без использования union all ?

Ну так сначала сделать union , а потом уже join.
5 мар 16, 13:18    [18900281]     Ответить | Цитировать Сообщить модератору
 Re: Несложный запрос  [new]
user89
Member

Откуда:
Сообщений: 2083
Glory,

спасибо.
5 мар 16, 23:04    [18901936]     Ответить | Цитировать Сообщить модератору
 Re: Несложный запрос  [new]
Дед-Папыхтет
Member [заблокирован]

Откуда:
Сообщений: 2808
user89,

+ так нет?
select m.idx, m.name, isnull(sub.itemID,ot.itemID) as itemID, isnull(sub.subName,ot.otName) as Name
from @main m
cross join (values (1),(2)) c(i)
left join @sub sub on m.idx = sub.idx and c.i=1
left join @ot ot on m.idx = ot.idx and c.i=2
5 мар 16, 23:15    [18901985]     Ответить | Цитировать Сообщить модератору
 Re: Несложный запрос  [new]
user89
Member

Откуда:
Сообщений: 2083
Дед-Папыхтет,

интересный вариант! По-любому в копилку знаний! Я погоняю на реальных данных, результат завтра напишу.
6 мар 16, 08:53    [18902638]     Ответить | Цитировать Сообщить модератору
 Re: Несложный запрос  [new]
invm
Member

Откуда: Москва
Сообщений: 9838
user89
интересный вариант!
Только учтите, что
а) нет гарантий, что по main будет "один проход";
б) без дополнительной фильтрации не эквивалентен варианту с union all.
6 мар 16, 12:15    [18902805]     Ответить | Цитировать Сообщить модератору
 Re: Несложный запрос  [new]
user89
Member

Откуда:
Сообщений: 2083
Самый затратный, но тоже работает
declare @main table (idx int, name varchar(50))
insert @main values (1,'Offer 01')
declare @sub table(idx int, itemID int, subName varchar(50))
insert @sub values (1,11,'sub 01'), (1,12,'sub 02'), (1,13,'sub 03')
declare @ot table(idx int, itemID int, otName varchar(50))
insert @ot values (1,21,'ot 01'), (1,22,'ot 02'), (1,23,'ot 03'), (1,24,'ot 04'), (1,25,'ot 05')

select m.idx, max(m.name) [name], isnull(sub.itemID,ot.itemID) [itemID],
case when grouping(sub.itemID)=1 then max(ot.otName) else max(sub.subName) end [subName]
from @main m
left join @sub sub on m.idx = sub.idx
left join @ot ot on m.idx = ot.idx
group by cube(m.idx, sub.itemID, ot.itemID)
having grouping(m.idx) = 0 and ((grouping(sub.itemID)=1 and grouping(ot.itemID)=0) or (grouping(sub.itemID)=0 and grouping(ot.itemID)=1))

В итоге остановился на варианте, где union вынесен в подзапрос:
;with un as (
  select * from @sub
  union all
  select * from @ot
)
select m.idx, m.name, un.itemID, un.subName
from @main m
left join un on m.idx = un.idx
7 мар 16, 19:17    [18906257]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить