因此,我的任务是创建一个 SQL Server 存储过程来组装员工的地理层次结构。
系统有 3 种地理类型:
- 国家地理(根)
- 区域地理(一级)
- 领土地理(2 级)
在数据库中,地理表看起来与此类似:
GeographyID | GeographyType | GeographyName | ParentGeographyID |
-----------------------------------------------------------------
1 National Nation NULL
2 Region South 1
3 Territory Florida 2
还有员工表。可以将一名员工分配到上述任何地区。
例如,如果员工 105 被分配到“南部”区域,则 XREF 表中会有一个条目,如下所示:
EmployeeID | GeographyID
------------------------
105 2
我需要做的是给定一个员工 ID,建立他们的地理层次结构。因此,员工 105 的结果将如下所示:
EmployeeID | TerritoryGeographyID | RegionGeographyID | NationalGeographyID
---------------------------------------------------------------------------
105 NULL 2 1
我不知道如何建立这样的数据结构。我希望有人能对这个问题有一些见解。
最佳答案
鉴于预期结果应该显示所有级别,并且级别很少,因此存在不使用递归CTE
的解决方案,例如
WITH G AS (
SELECT g.GeographyID
, t.GeographyID TerritoryGeographyID
, r.GeographyID RegionGeographyID
, n.GeographyID NationalGeographyID
FROM Geography g
LEFT JOIN Geography T ON (g.GeographyID = T.GeographyID)
AND (T.GeographyType = 'Territory')
LEFT JOIN Geography R ON ((g.GeographyID = R.GeographyID)
OR (R.GeographyID = T.ParentGeographyID))
AND (R.GeographyType = 'Region')
LEFT JOIN Geography N ON ((g.GeographyID = N.GeographyID)
OR (N.GeographyID = R.ParentGeographyID))
AND (N.GeographyType = 'National')
)
SELECT E.EmployeeID
, TerritoryGeographyID
, RegionGeographyID
, NationalGeographyID
FROM Employee E
INNER JOIN G ON E.GeographyID = G.GeographyID;
在CTE
中,Geography
从垂直到水平进行分区和重组,主要查询JOIN
'PIVOT
ed'数据到员工数据,可以通过将[trn].GeographyID
更改为[trn].GeographyName
可以明确划分,为每个级别定义一个CTE
With N AS (
SELECT GeographyID, GeographyName
FROM Geography
WHERE GeographyType = 'National'
), R AS (
SELECT GeographyID, GeographyName, ParentGeographyID
FROM Geography
WHERE GeographyType = 'Region'
), T AS (
SELECT GeographyID, GeographyName, ParentGeographyID
FROM Geography
WHERE GeographyType = 'Territory'
), G AS (
SELECT g.GeographyID
, t.GeographyID TerritoryGeographyID
, r.GeographyID RegionGeographyID
, n.GeographyID NationalGeographyID
FROM Geography g
LEFT JOIN Geography T ON (g.GeographyID = T.GeographyID)
LEFT JOIN Geography R ON (g.GeographyID = R.GeographyID)
OR (R.GeographyID = T.ParentGeographyID)
LEFT JOIN Geography N ON (g.GeographyID = N.GeographyID)
OR (N.GeographyID = R.ParentGeographyID)
)
SELECT E.EmployeeID
, TerritoryGeographyID
, RegionGeographyID
, NationalGeographyID
FROM Employee E
INNER JOIN G ON E.GeographyID = G.GeographyID;
关于sql - 在 SQL Server 中创建数据层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24306931/