私はこれをSQL EXPRESS 2016で試しました。これが私の問題です:
構造DB(親>子>孫> ...)のようなツリーがあり、下位レベルには別のテーブルとの関係があります。
表1
CREATE TABLE [dbo].[Equipament]
[ID] [nvarchar](50) NOT NULL,
[AL] [nvarchar](50) NULL,
[Lvl] [nvarchar](50) NULL,
[IDParent] [nvarchar](50) NULL,
表2
CREATE TABLE [dbo].[Conns]
[Conns] [nvarchar](50) NOT NULL,
[IDEquip] [nvarchar](50) NOT NULL,
FOREIGN KEY([IDEquip])
REFERENCES [dbo].[Equipament] ([ID])
私が取得しようとしているのは、再帰的に取得するCTEです。
主にConnsテーブルにレベル1および2の機器がなく、LEFT JOIN
再帰CTE。
私が得た最も近いものはこれです:
;WITH QUERY AS
(
SELECT E.ID,E.IDParent,L.conns
FROM Equipament E
LEFT JOIN conns L ON E.ID=L.IDEquip
WHERE E.IDParent IS NULL
UNION ALL
SELECT E.ID,E.IDParent,L.conns
FROM Equipament E
JOIN conns L ON E.ID = L.IDEquip
JOIN QUERY P on P.ID = E.IDParent
)
SELECT
E.ID,
SUM(S.Total) AS LTotal
FROM Equipament E
LEFT JOIN ( SELECT Q.ID, COUNT(Q.conns) AS Total
FROM QUERY Q
GROUP BY Q.ID
) as S
ON E.ID = S.ID
GROUP BY E.ID
ORDER BY E.ID
option (maxrecursion 0)
[〜#〜] edit [〜#〜]要求されたフィドル: dbfiddle link
サンプルデータでは、予想される出力は次のようになります。
+---+-------------------------------------+
|ID | Total Conections Dependancy |
+---+-------------------------------------+
|AA | 1 (CE + BA) |
|AB | 4 ( BB + BC) |
|BA | 0 |
|BB | 0 |
|BC | 4 ( CD + CB) |
|CA | 0 |
|CB | 3 |
|CD | 1 |
|CE | 1 |
+---+-------------------------------------+
Cレベルの機器のみに接続があり、レベルAからレベルCに直接ジャンプする可能性があります。
これは可能ですか?誰かが私を正しい方向に向けることができますか?
ありがとうございました、
はい、再帰的なCTEまたは再帰的な関数のいずれかを使用してそれを行うことが可能です(最初はCTEを使用してそれを解決する方法を理解できなかったため、関数を使用してソリューションをコーディングしました。 、私もそれを答えに留めています)。方法は次のとおりです。
;WITH QUERY AS
(
SELECT IDEquip, 1 AS Quantity
FROM Conns
UNION ALL
SELECT E.IDParent AS IDEquip, 1 AS Quantity
FROM Equipament E
INNER JOIN QUERY Q ON E.ID = Q.IDEquip
)
SELECT E.ID, ISNULL(SUM(Q.Quantity), 0) AS Total
FROM Equipament E
LEFT JOIN QUERY Q ON E.ID = Q.IDEquip
GROUP BY E.ID;
再帰的なCTEを使用してそれを解決するコツは、値を後ろから前にクエリすることでした。
CREATE FUNCTION dbo.GetAllDescendants(@id nvarchar(100))
RETURNS INT
AS
BEGIN
RETURN(
SELECT SUM(Total + ISNULL(dbo.GetAllDescendants(ID), 0))
FROM (
SELECT ID, IDParent, COUNT(IDEquip) AS Total
FROM Equipament
LEFT JOIN Conns ON ID = IDEquip
GROUP BY ID, IDParent
) AS TotalConns
WHERE IDParent = @id
)
END;
このクエリを使用すると、子孫の合計を取得できますが、ID自体の接続は取得できません。
SELECT ID, ISNULL(dbo.GetAllDescendants(ID), 0) AS [Total Conections Dependancy]
FROM Equipament
ORDER BY ID;
説明したとおりの結果を得るには、次のように実行する必要があります。
SELECT ID, IIF(COUNT(IDEquip) > 0, COUNT(IDEquip), ISNULL(dbo.GetAllDescendants(ID), 0)) AS [Total Conections Dependancy]
FROM Equipament
LEFT JOIN Conns ON ID = IDEquip
GROUP BY ID, IDParent
ORDER BY ID;