当执行CTE表达通过换挡来查询有序的孩子父母的关系,它失败
算术溢出错误将表达式转换为数据类型BIGINT
问题是,移位值变大很容易。我知道我可以增加数据类型支持38个数值,但具有深厚的父子关系时,我还是会打这个号码。我想知道是否有任何其他方法来排序的结果,所以我不会打这个限制。
下面是一个示例脚本,显示的移位参数的增大。
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))
输出,而不移位参数
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
与移位参数输出(期望的)
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
假设我们可以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,但似乎导致这一问题表示反正(暧昧编码)。