Pet*_*son 7 sql t-sql sql-server select
假设我有一个表格Events,其数据类似于以下内容:
ID | Name | ParentEvent
----+----------------+-----------------
0 | Happy Event | NULL
1 | Sad Event | NULL
2 |Very Happy Event| 0
3 | Very Sad Event | 1
4 | Happiest Event | 2
5 |Unpleasant Event| 1
Run Code Online (Sandbox Code Playgroud)
如何查询此表以获得以这种方式返回的结果
ParentEvent的事件在事件发生后直接出现,并进行ID数学计算ParentEventParentEvent的事件的深度为0.如果事件的深度为n,则其为父项的任何事件的深度为n + 1.对于上面给出的表,我想得到一个看起来像的结果集
ID | Name | ParentEvent | Depth |
----+----------------+--------------+--------+
0 | Happy Event | NULL | 0 |
2 |Very Happy Event| 0 | 1 |
4 | Happiest Event | 2 | 2 |
1 | Sad Event | NULL | 0 |
3 | Very Sad Event | 1 | 1 |
5 |Unpleasant Event| 1 | 1 |
Run Code Online (Sandbox Code Playgroud)
如何构造SQL查询以获取此结果集?我正在使用T-SQL,但如果您可以在任何SQL风格中执行此操作,请继续回答.
以下查询都返回您要求的确切结果集.所有这些工作都是通过计算根节点的完整路径,并使用一些技术使该路径能够被排序.
SQL Server 2008及更高版本.在这里,通过转换为hierarchyid数据类型,SQL Server可以正确处理排序.
WITH Data AS (
SELECT
ID,
Name,
ParentID,
Depth = 0,
Ancestry = '/' + Convert(varchar(max), ID) + '/'
FROM
hierarchy
WHERE
ParentID IS NULL
UNION ALL
SELECT
H.ID,
H.Name,
H.ParentID,
D.Depth + 1,
Ancestry = D.Ancestry + Convert(varchar(max), H.ID) + '/'
FROM
Data D
INNER JOIN hierarchy H
ON H.ParentID = D.ID
)
SELECT
ID,
Name,
ParentID,
Depth
FROM Data
ORDER BY Convert(hierarchyid, Ancestry);
Run Code Online (Sandbox Code Playgroud)
SQL Server 2005及以上版本.我们可以将ID值转换为字符串并填充它们以便排序.
WITH Data AS (
SELECT
ID,
Name,
ParentID,
Depth = 0,
Ancestry = Right('0000000000' + Convert(varchar(max), ID), 10)
FROM
hierarchy
WHERE
ParentID IS NULL
UNION ALL
SELECT
H.ID,
H.Name,
H.ParentID,
Depth + 1,
Ancestry = D.Ancestry + Right('0000000000' + Convert(varchar(max), H.ID), 10)
FROM
Data D
INNER JOIN hierarchy H
ON H.ParentID = D.ID
)
SELECT
ID,
Name,
ParentID,
Depth
FROM Data
ORDER BY Ancestry;
Run Code Online (Sandbox Code Playgroud)
我们也可以使用varbinary(否则,这与先前的查询相同):
WITH Data AS (
SELECT
ID,
Name,
ParentID,
Depth = 0,
Ancestry = Convert(varbinary(max), Convert(varbinary(4), ID))
FROM
hierarchy
WHERE
ParentID IS NULL
UNION ALL
SELECT
H.ID,
H.Name,
H.ParentID,
Depth + 1,
Ancestry = D.Ancestry + Convert(varbinary(4), H.ID)
FROM
Data D
INNER JOIN hierarchy H
ON H.ParentID = D.ID
)
SELECT
ID,
Name,
ParentID,
Depth
FROM Data
ORDER BY Ancestry;
Run Code Online (Sandbox Code Playgroud)
SQL Server 2000及更高版本,允许树最多深度为800级:
SELECT
*,
Ancestry = CASE WHEN ParentID IS NULL THEN Convert(varchar(8000), Right('0000000000' + Convert(varchar(10), ID), 10)) ELSE '' END,
Depth = 0
INTO #hierarchy
FROM hierarchy;
WHILE @@RowCount > 0 BEGIN
UPDATE H
SET
H.Ancestry = P.Ancestry + Right('0000000000' + Convert(varchar(8000), H.ID), 10),
H.Depth = P.Depth + 1
FROM
#hierarchy H
INNER JOIN #hierarchy P
ON H.ParentID = P.ID
WHERE
H.Ancestry = ''
AND P.Ancestry <> '';
END;
SELECT
ID,
Name,
ParentID,
Depth
FROM #hierarchy
ORDER BY Ancestry;
DROP TABLE #hierarchy;
Run Code Online (Sandbox Code Playgroud)
varbinary可以进行相同的转换,允许最多2000级.
| 归档时间: |
|
| 查看次数: |
203 次 |
| 最近记录: |