У меня есть таблица с родительским/дочерним отношением вместе с созданной датой колонкой, ссылающейся на себя. Я хочу показать каждую родительскую запись и все потомки, упорядоченные по последнему «действию» на узле. Итак, если строка номер 1, которая была создана давно, добавила к ней нового ребенка (например, новый ребенок добавлен к одному из его дочерних элементов, например), то я хочу, чтобы это было в верхней части результатов.CTE с рекурсией - row_number() aggregated
У меня возникли проблемы с тем, чтобы это работало в настоящее время.
Моя структура таблицы выглядит следующим образом:
CREATE TABLE [dbo].[Orders](
[OrderId] [int] NOT NULL,
[Orders_OrderId] [int] NULL,
[DateOrdered] datetime)
Я написал следующий SQL, чтобы вытащить информацию из:
WITH allOrders AS
(SELECT po.orderid, po.Orders_OrderId, po.DateOrdered, 0 as distance,
row_number() over (order by DateOrdered desc) as RN1
FROM orders po WHERE po.Orders_OrderId is null
UNION ALL
SELECT b2.orderid ,b2.Orders_OrderId, b2.DateOrdered, c.distance + 1,
c.RN1
FROM orders b2
INNER JOIN allOrders c
ON b2.Orders_OrderId = c.orderid
)
SELECT * from allOrders
where RN1 between 0 and 2
order by rn1 asc, distance asc
Есть ли способ, что я могу «агрегатные» Результаты работы рекурсивный выбор, чтобы я мог выбрать максимальную дату на всем «родительском» узле?
SQLFiddle демонстрация: http://sqlfiddle.com/#!3/ca6cb/11 (запись номер 1 должен быть первым, как она есть ребенок, который был обновлен недавно)
Update Благодаря предложению от @twrowsell У меня есть следующий запрос, который делает работает, но кажется действительно неуклюжим и имеет некоторые проблемы с производительностью, я чувствую, что мне не нужно иметь 3 CTE для достижения этого. Можно ли его сконфигурировать, сохраняя «номера строк» (как это показано на дисплее пользователя с пейджингом)?
WITH allOrders AS
(SELECT po.orderid, po.Orders_OrderId, 0 as distance, po.DateOrdered, po.orderid as [rootId]
FROM orders po WHERE po.Orders_OrderId is null
UNION ALL
SELECT b2.orderid ,b2.Orders_OrderId, c.distance + 1, b2.DateOrdered, c.[rootId]
FROM orders b2
INNER JOIN allOrders c
ON b2.Orders_OrderId = c.orderid
),
mostRecentOrders as (
SELECT *,
MAX(DateOrdered) OVER (PARTITION BY rootId) as [HighestOrderId]
from allOrders
),
pagedOrders as (
select *, dense_rank() over (order by [HighestOrderId] desc) as [PagedRowNumber] from mostRecentOrders)
SELECT * from pagedOrders
where PagedRowNumber between 0 and 2
order by [HighestOrderId] desc
Кроме того, я мог бы использовать в качестве MAX(orderid)
OrderID является идент и datecreated не может быть обновлен в моем сценарии после его создания.
Обновлено SQLFiddle: http://sqlfiddle.com/#!3/ca6cb/41
Какая версия SQL Server вы используете? –
@JonSenchyna SQL 2008 –
@EdW, Просто покажите свое желание, полученное из данных образца в скрипке. – KumarHarsh