これが私のデータ構造です:
CREATE TABLE Locations(
LocID int IDENTITY(1,1) NOT NULL,
LocationTypeID int NOT NULL,
ParentID int NULL,
LocNum varchar(50) NULL,
LocName varchar(250) NULL,
)
CREATE TABLE LocationTypes(
LocationTypeID int IDENTITY(1,1) NOT NULL,
TypeName varchar(50) NOT NULL
)
LocationTypesテーブルには、次の値が含まれています。
+----------------+----------+
| LocationTypeID | TypeName |
+----------------+----------+
| 1 | Campus |
| 2 | Building |
| 3 | Area |
| 4 | Floor |
| 5 | Room |
+----------------+----------+
Locations
テーブルには、ParentID
がnull(キャンパス)である場所や、ParentID
がある場所など、さまざまな場所が含まれています。 LocationTypes
テーブルに示されているように、データ構造には5つのレベルの階層があります。キャンパス(1)は最も限定的ではなく、ルーム(5)は最も限定的です。私のデータベースにはLocID
を参照する他のテーブルがありますが、ほとんどの場合、これらのテーブルはLocationTypeID
が5
の場所を参照していますが、常にそうではありません。
エンドユーザーに表示するために、階層内のすべての場所の名前を取得する必要があります。
最終的に取得したいのは、次の構造を持つビュー(またはキャッシュされたテーブル)です。
+-------+---------------+-----------------+-------------+--------------+-------------+
| LocID | CampusLocName | BuildingLocName | AreaLocName | FloorLocName | RoomLocName |
+-------+---------------+-----------------+-------------+--------------+-------------+
LocationTypeID
が5
以外のLocationsの場合、これらの列の一部がnullになることに気づきましたが、これはまったく問題ありません。
私はおそらく再帰的な共通テーブル式が必要であることを知っています。
基本的に、このための疑似コードロジックは次のとおりです。
Location
のForeach LocationsTable
Location
のParent Location
を取得し、親がなくなるまで再帰的に続行しますLocID
を参照する他のテーブルで簡単にLEFT JOIN
edできるようにします。すべてが理にかなっていることを願っています。私を助けることができる人に感謝します。
私はあなたがこのクエリで望ましい結果を達成できると信じています:
;WITH CTE_Locations (LocID, CampusLocName, BuildingLocName, AreaLocName, FloorLocName, RoomLocName)
AS
(
SELECT LocID,
LocName AS CampusLocName,
CONVERT(varchar(250), NULL) AS BuildingLocName,
CONVERT(varchar(250), NULL) AS AreaLocName,
CONVERT(varchar(250), NULL) AS FloorLocName,
CONVERT(varchar(250), NULL) AS RoomLocName
FROM Locations
WHERE ParentID IS NULL
UNION ALL
SELECT L.LocID,
CampusLocName,
IIF(L.LocationTypeID = 2, LocName, BuildingLocName) AS BuildingLocName,
IIF(L.LocationTypeID = 3, LocName, AreaLocName) AS AreaLocName,
IIF(L.LocationTypeID = 4, LocName, FloorLocName) AS FloorLocName,
IIF(L.LocationTypeID = 5, LocName, RoomLocName) AS RoomLocName
FROM Locations L
INNER JOIN CTE_Locations CTE ON L.ParentID = CTE.LocID
)
SELECT LocID, CampusLocName, BuildingLocName, AreaLocName, FloorLocName, RoomLocName
FROM CTE_Locations;
WITH common_table_expression docによると:
この句は、定義するSELECTステートメントの一部としてCREATE VIEWステートメントでも使用できます。