SQL查询层级号
SQL query for hierarchical number
这是数据:
CREATE TABLE dbo.Correspondents
(
ID smallint NOT NULL,
ParentID smallint NULL,
Name nvarchar(30) NOT NULL,
OrderNumber int NOT NULL
);
INSERT INTO dbo.Correspondents VALUES
(1, null, 'A', 1),
(2, 1, 'B', 2),
(3, 1, 'C', 3),
(4, 2, 'D', 1);
我想要的结果:
ID|Name|HierarchicalNumber
1 | A| 1
2 | B| 1.2
3 | C| 1.3
4 | D| 1.2.1
线索是每个条目都有自己的订单号,但查询应该 return 包含所有父编号的层次编号作为子序列,由末尾带有自己编号的点分隔。主要功能要求能够为任何条目提供层次编号,因此查询应该能够接收条目的 ID 并 return 它的层次编号。数据库管理系统是 MSSQL 2017。
提前致谢!
你想要递归 CTE
with h as (
select *, cast(OrderNumber as varchar(max)) hid
from dbo.Correspondents
where ParentID is null
union all
select c.*, h.hid + '.' + cast(c.OrderNumber as varchar(10))
from dbo.Correspondents c
join h on h.id= c.ParentID
)
select *
from h
order by hid;
它也可以重构为 TVF
create function gethid(@id int) returns table
as return
with h as (
select *, cast(OrderNumber as varchar(max)) hid
from dbo.Correspondents
where ParentID is null
union all
select c.*, h.hid + '.' + cast(c.OrderNumber as varchar(10))
from dbo.Correspondents c
join h on h.id= c.ParentID
-- stop when @id is found
and h.id != @id
)
select *
from h
where id = @id;
看起来像一个简单的递归查询,在其中构建层次结构字符串,从您正在获取的新行的父行中已有的内容开始 - 作为连续的字符串连接。
像下面一样 - 或者您正在寻找其他东西?
WITH rec AS (
SELECT
id
, name
, CAST(id AS VARCHAR(16)) AS hierarchicalnumber
FROM correspondents
WHERE parentid IS NULL
UNION ALL
SELECT
correspondents.id
, correspondents.name
, rec.hierarchicalnumber
+ '.'
+ CAST(correspondents.id AS VARCHAR(16)) AS hierarchialnumber
FROM correspondents JOIN rec ON rec.id = correspondents.parentid
)
SELECT * FROM rec;
-- out id | name | hierarchicalnumber
-- out ----+------+--------------------
-- out 1 | A | 1
-- out 2 | B | 1.2
-- out 3 | C | 1.3
-- out 4 | D | 1.2.4
这是数据:
CREATE TABLE dbo.Correspondents
(
ID smallint NOT NULL,
ParentID smallint NULL,
Name nvarchar(30) NOT NULL,
OrderNumber int NOT NULL
);
INSERT INTO dbo.Correspondents VALUES
(1, null, 'A', 1),
(2, 1, 'B', 2),
(3, 1, 'C', 3),
(4, 2, 'D', 1);
我想要的结果:
ID|Name|HierarchicalNumber
1 | A| 1
2 | B| 1.2
3 | C| 1.3
4 | D| 1.2.1
线索是每个条目都有自己的订单号,但查询应该 return 包含所有父编号的层次编号作为子序列,由末尾带有自己编号的点分隔。主要功能要求能够为任何条目提供层次编号,因此查询应该能够接收条目的 ID 并 return 它的层次编号。数据库管理系统是 MSSQL 2017。 提前致谢!
你想要递归 CTE
with h as (
select *, cast(OrderNumber as varchar(max)) hid
from dbo.Correspondents
where ParentID is null
union all
select c.*, h.hid + '.' + cast(c.OrderNumber as varchar(10))
from dbo.Correspondents c
join h on h.id= c.ParentID
)
select *
from h
order by hid;
它也可以重构为 TVF
create function gethid(@id int) returns table
as return
with h as (
select *, cast(OrderNumber as varchar(max)) hid
from dbo.Correspondents
where ParentID is null
union all
select c.*, h.hid + '.' + cast(c.OrderNumber as varchar(10))
from dbo.Correspondents c
join h on h.id= c.ParentID
-- stop when @id is found
and h.id != @id
)
select *
from h
where id = @id;
看起来像一个简单的递归查询,在其中构建层次结构字符串,从您正在获取的新行的父行中已有的内容开始 - 作为连续的字符串连接。
像下面一样 - 或者您正在寻找其他东西?
WITH rec AS (
SELECT
id
, name
, CAST(id AS VARCHAR(16)) AS hierarchicalnumber
FROM correspondents
WHERE parentid IS NULL
UNION ALL
SELECT
correspondents.id
, correspondents.name
, rec.hierarchicalnumber
+ '.'
+ CAST(correspondents.id AS VARCHAR(16)) AS hierarchialnumber
FROM correspondents JOIN rec ON rec.id = correspondents.parentid
)
SELECT * FROM rec;
-- out id | name | hierarchicalnumber
-- out ----+------+--------------------
-- out 1 | A | 1
-- out 2 | B | 1.2
-- out 3 | C | 1.3
-- out 4 | D | 1.2.4