Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 OUTER JOIN к OUTER APPLY - как?  [new]
Джон Апплай
Guest
Ситуация: имеется некий XML, его нужно разобрать, показать на клиенте, и, если клиент одобряет, записать в базу. Для отображения используется запрос, который разбирает XML с помощью XQuery, и, никуда не записывая данные, возвращает клиенту выборку. XML достаточно заковыристый с т.з. структуры, и нужно джойнить внешним соединением отдельные наборы данных, извлекаемых из этого XML. Эти отдельные наборы формируются с помощью outer apply - вопрос, как их сджойнить? Пример (максимально упрощенный):
declare
  @xml xml;
set @xml=N'<root><item1 id="1" /><item2 id="2" /></root>';
select item1.*, item2.*
from @xml.nodes('/root') x_root(n)
outer apply x_root.n.nodes('item1') x_item1(n)
outer apply x_root.n.nodes('item2') x_item2(n)
outer apply (
  select
    x_item1.n.value('@id', 'int') id
) item1
outer apply (
  select
    x_item2.n.value('@id', 'int') id
) item2 on item2.id=item1.id

- разумеется, это не работает (incorrect syntax near on) (а хотелось бы).
Пробовал так:
select item1.*, item2.*
from @xml.nodes('/root') x_root(n)
outer apply x_root.n.nodes('item1') x_item1(n)
outer apply x_root.n.nodes('item2') x_item2(n)
outer apply (
  select
    x_item1.n.value('@id', 'int') id
) item1
left join (
  select
    t.n.value('@id', 'int') id
  from x_item2.n.nodes('.') t(n)
) item2 on item2.id=item1.id

или так
select item1.*, item2.*
from @xml.nodes('/root') x_root(n)
outer apply x_root.n.nodes('item1') x_item1(n)
outer apply (
  select
    x_item1.n.value('@id', 'int') id
) item1
left join (
  select
    x_item2.n.value('@id', 'int') id
  from x_root.n.nodes('item2') x_item2(n)
) item2 on item2.id=item1.id

- тоже не работает, ошибки:

Msg 107, Level 15, State 1, Line 20
The column prefix 'x_item2' does not match with a table name or alias name used in the query.
Msg 9506, Level 16, State 1, Line 20
The XMLDT method 'nodes' can only be invoked on columns of type xml.

Работает вот так:
select item1.*, item2.*
from @xml.nodes('/root') x_root(n)
outer apply x_root.n.nodes('item1') x_item1(n)
outer apply x_root.n.nodes('item2') x_item2(n)
outer apply (
  select
    x_item1.n.value('@id', 'int') id
) item1
outer apply (
  select v.* from (
    select
      x_item2.n.value('@id', 'int') id
  ) v
  where v.id=item1.id
) item2

- но это как-то громоздко, и не особенно наглядно. Есть ли другие способы внешнего объединения результатов OUTER APPLY?
18 дек 15, 11:45    [18577163]     Ответить | Цитировать Сообщить модератору
 Re: OUTER JOIN к OUTER APPLY - как?  [new]
Glory
Member

Откуда:
Сообщений: 104751
Джон Апплай
Эти отдельные наборы формируются с помощью outer apply - вопрос, как их сджойнить?

select *
from (здесь запрос для 1го отдельного набора) a
join
(здесь запрос для 2го отдельного набора) b on <здесь условия соединения отдельных наборов>
18 дек 15, 12:08    [18577333]     Ответить | Цитировать Сообщить модератору
 Re: OUTER JOIN к OUTER APPLY - как?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8805
А почему Вы не хотите XML разбирать на клиенте же? Зачем его отправлять на сервер, разбирать и возвращать клиенту?
18 дек 15, 12:17    [18577406]     Ответить | Цитировать Сообщить модератору
 Re: OUTER JOIN к OUTER APPLY - как?  [new]
Джон Апплай
Guest
Владислав Колосов,

А как вы себе представляете разбор XML на клиенте в реляционный набор данных, чтобы потом его отобразить, например, в средстве формирования отчетности, работающем с реляционными наборами данных? Разобрать на стороне БД в данном случае проще всего - xml по объему не особенно большой, и нагрузка на БД будет невелика.

Glory,

спасибо, я в курсе такой конструкции, но мне не хотелось бы в каждом подзапросе разбирать XML от корня. Погуглив, я понял, как называется в общем случае то, чего мне хочется - correlated subquery join. Судя по поисковой выдаче, такое в MSSQL не поддерживается.
18 дек 15, 12:36    [18577540]     Ответить | Цитировать Сообщить модератору
 Re: OUTER JOIN к OUTER APPLY - как?  [new]
Glory
Member

Откуда:
Сообщений: 104751
Джон Апплай
но мне не хотелось бы в каждом подзапросе разбирать XML от корня.

Тогда выгрузите полностью разобранный xml в таблицу
18 дек 15, 12:41    [18577571]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить