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

Откуда: glubinka
Сообщений: 4240
create table a (aid int, parentid int, level int, root int, path sysname)
insert into a (aid, parentid, level, root, path) values (1, 0, 1, 1, '1')
insert into a (aid, parentid, level, root, path) values (2, 1, 2, 1, '1->2')
insert into a (aid, parentid, level, root, path) values (3, 2, 3, 1, '1->2->3')
GO

create table j (jid int, aid int, val float )
insert into j (jid, aid, val) values (44, 1, 5.0)
insert into j (jid, aid, val) values (55, 2, 6.0)
insert into j (jid, aid, val) values (66, 3, 7.0)


Как модифицировать cross apple - или что-то иное надо чтобы получить такой выход?

родитетельскому a добавить все вхождения j от детей.

select a.aid, parentid, level, root, path, jid, val from a cross apply j order by 1 asc


aid, parentid, level, root,     path,   jid,    val
1 0 1 1 1 44 5
1 0 1 1 1 55 6
1 0 1 1 1 66 7

2 1 2 1 1->2 55 6
2 1 2 1 1->2 66 7

3 2 3 1 1->2->3 66 7
17 май 19, 19:54    [21887596]     Ответить | Цитировать Сообщить модератору
 Re: cross apply на дерево  [new]
Lepsik
Member

Откуда: glubinka
Сообщений: 4240
Будет ли единственным такое решение?

SELECT a.aid, parentid, level, root, path, jid, val 
FROM (select a1.aid, a1.parentid, a1.level, a1.root, a1.path from a a1 cross apply a a2 where a1.level <= a2.level) a 
LEFT JOIN j ON a.aid = j.aid
order by 1 asc
17 май 19, 21:48    [21887653]     Ответить | Цитировать Сообщить модератору
 Re: cross apply на дерево  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 927
Lepsik,

CREATE TABLE #a ( [aid] INT, [aidparent] INT )
INSERT INTO #a
VALUES 
  ( 1, 0 ),
  ( 2, 1 ),
  ( 3, 2 )
;
CREATE TABLE #j ( [jid] INT, [aid] INT, [val] FLOAT )
INSERT INTO #j
VALUES 
  ( 44, 1, 5.0 ),
  ( 55, 2, 6.0 ),
  ( 66, 3, 7.0 )
;
WITH
cte AS (
  SELECT
    [aidroot] = a.[aid],
    a.*
  FROM
    #a a
  UNION ALL
  SELECT
    [aidroot] = cte.[aidroot],
    a.*
  FROM
    cte
    INNER JOIN #a a ON ( a.[aidparent] = cte.[aid] )
)
SELECT
  cte.[aidroot],
  cte.[aid],
  j.[jid],
  j.[val]
FROM
  cte
  LEFT JOIN #j j ON (
        j.[aid] = cte.[aid] )
ORDER BY
  [aidroot],
  [aid]
;
DROP TABLE #a
DROP TABLE #j
;
20 май 19, 10:56    [21888639]     Ответить | Цитировать Сообщить модератору
 Re: cross apply на дерево  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 927
Lepsik
Будет ли единственным такое решение?


Не только не будет, но еще и не правильным.
20 май 19, 10:58    [21888643]     Ответить | Цитировать Сообщить модератору
 Re: cross apply на дерево  [new]
Lepsik
Member

Откуда: glubinka
Сообщений: 4240
Почему нет? результат на лицо. Сравнение по root только добавить если другие ветви будут.

SELECT a.aid, parentid, level, root, path, jid, val 
FROM (select a1.aid, a1.parentid, a1.level, a1.root, a1.path from a a1 cross apply a a2 where a1.level <= a2.level  and a1.root=a2.root  ) a 
LEFT JOIN j ON a.aid = j.aid
order by 1 asc
21 май 19, 03:55    [21889328]     Ответить | Цитировать Сообщить модератору
 Re: cross apply на дерево  [new]
Lepsik
Member

Откуда: glubinka
Сообщений: 4240
у вас output неверный
21 май 19, 03:58    [21889329]     Ответить | Цитировать Сообщить модератору
 Re: cross apply на дерево  [new]
Lepsik
Member

Откуда: glubinka
Сообщений: 4240
Прошу прошения - я затупил. Был неправ.

Правильно будет:

SELECT a.aid, parentid, level, root, path, jid, val 
FROM (select a1.aid, a1.parentid, a1.level, a1.root, a1.path from a a1 cross apply a a2 where a1.level >= a2.level and a1.root=a2.root ) a 
LEFT JOIN j ON a.aid = j.aid
order by 1 asc
21 май 19, 04:01    [21889331]     Ответить | Цитировать Сообщить модератору
 Re: cross apply на дерево  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 927
Lepsik
Правильно будет

А теперь усложним пример до "реального"
create table a (aid int, parentid int, level int, root int, path sysname)
insert into a (aid, parentid, level, root, path) values (1, 0, 1, 1, '1')
insert into a (aid, parentid, level, root, path) values (2, 1, 2, 1, '1->2')
insert into a (aid, parentid, level, root, path) values (3, 2, 3, 1, '1->2->3')
insert into a (aid, parentid, level, root, path) values (4, 1, 2, 1, '1->4')
insert into a (aid, parentid, level, root, path) values (5, 4, 3, 1, '1->4->5')

Lepsik
Был неправ.

Ты продолжаешь быть не прав.
Lepsik
Прошу прошения - я затупил.

Я тебя прощаю, а вот SQL - нет.
21 май 19, 16:25    [21889878]     Ответить | Цитировать Сообщить модератору
 Re: cross apply на дерево  [new]
Lepsik
Member

Откуда: glubinka
Сообщений: 4240
Ваш output недостоверен

для id = 1 parentid должен быть равен 0.

aid parentid, val
1, 0, 5
1, 0, 6
1, 0, 7

он будет более достоверен, если будет такой.

SELECT cte.[aidroot] AS aid, a.[aidparent], j.[jid], j.[val] FROM cte LEFT JOIN #j j ON ( j.[aid] = cte.[aid] )
JOIN #a a ON a.aid = cte.[aidroot]
21 май 19, 21:25    [21890077]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить