在执行CTE表达式以通过移位查询有序的子级父关系时,它会失败
将表达式转换为数据类型bigint的算术溢出错误
问题是平移值非常容易变大。我知道我可以增加数据类型以支持38个数字值,但是在与深层父子关系时,我仍然会达到这个数字。我想知道是否还有其他方法可以对结果进行排序,所以我不会达到此限制。
这是一个示例脚本,显示了shift参数的增加。
CREATE TABLE [dbo].[ParentChild] (
[Id] [int] IDENTITY(1,1) NOT NULL,
[ParentId] [int] NULL,
[Name] [nvarchar](150) NOT NULL
CONSTRAINT [PK_Dialog] PRIMARY KEY CLUSTERED
(
[Id] ASC
))
GO
ALTER TABLE [dbo].[ParentChild] WITH CHECK ADD CONSTRAINT [FK_ParentChild_ParentId] FOREIGN KEY([ParentId])
REFERENCES [dbo].[ParentChild] ([Id])
GO
ALTER TABLE [dbo].[ParentChild] CHECK CONSTRAINT [FK_ParentChild_ParentId]
GO
set identity_insert [dbo].[ParentChild] on
insert into [dbo].[ParentChild] ([Id], [ParentId],[Name])
values
(1, NULL, '1'),
(2, NULL, '2'),
(3, 1, '1.1'),
(4, 1, '1.2'),
(5, 2, '2.1'),
(6, 5, '2.1.1')
set identity_insert [dbo].[ParentChild] off
-- without shift
with Parent as (
select d1.[Id], d1.[ParentId], d1.[Name], 0 AS [Level]
FROM [dbo].[ParentChild] as d1
WHERE d1.[ParentId] IS NULL
UNION ALL
SELECT d2.Id, d2.ParentId, d2.[Name], [Level] + 1
FROM [dbo].[ParentChild] as d2
INNER JOIN Parent d1 ON d1.[Id] = d2.ParentId
)
select p.Id, p.ParentId, p.[Name], [Level]
from Parent p
group by p.Id, p.ParentId, p.[Name], [Level];
-- desired
with Parent as (
select d1.[Id], d1.[ParentId], d1.[Name], 0 AS [Level],
CAST(row_number() over(order by id) as DECIMAL(38,0)) as [shift]
FROM [dbo].[ParentChild] as d1
WHERE d1.[ParentId] IS NULL
UNION ALL
SELECT d2.Id, d2.ParentId, d2.[Name], [Level] + 1,
CAST([shift] * 100 + row_number() over(order by d2.id) as DECIMAL(38,0))
FROM [dbo].[ParentChild] as d2
INNER JOIN Parent d1 ON d1.[Id] = d2.ParentId
)
select p.Id, p.ParentId, p.[Name], [Level], [shift]
from Parent p
group by p.Id, p.ParentId, p.[Name], [Level], [shift]
order by cast([shift] as varchar(50))
不带shift参数的输出
Id ParentId Name Level
1 NULL 1 0
2 NULL 2 0
3 1 1.1 1
4 1 1.2 1
5 2 2.1 1
6 5 2.1.1 2
带有shift参数的输出(所需)
Id ParentId Name Level shift
1 NULL 1 0 1
3 1 1.1 1 101
4 1 1.2 1 102
2 NULL 2 0 2
5 2 2.1 1 201
6 5 2.1.1 2 20101
答案 0 :(得分:1)
假设我们可以将shift
设置为字符串而不是支持数学的数据类型,我们可以这样做:
with Parent as (
select d1.[Id], d1.[ParentId], d1.[Name], 0 AS [Level],
CONVERT(varchar(max),row_number() over(order by id)) as [shift]
FROM [dbo].[ParentChild] as d1
WHERE d1.[ParentId] IS NULL
UNION ALL
SELECT d2.Id, d2.ParentId, d2.[Name], [Level] + 1,
shift + RIGHT('0' + CONVERT(varchar(2),row_number() over(order by d2.id)),2)
FROM [dbo].[ParentChild] as d2
INNER JOIN Parent d1 ON d1.[Id] = d2.ParentId
)
select p.Id, p.ParentId, p.[Name], [Level], [shift]
from Parent p
group by p.Id, p.ParentId, p.[Name], [Level], [shift]
order by shift
如果行数超过100,则会产生不同的结果,但这似乎仍然会导致这种表示形式的问题(模糊编码)。