対応のないグラフのすべての接続されたサブグラフを見つける方法その他表:
id
識別子2
&] 1 | ||
---|---|---|
2 | b | |
3 | &] g | |
4 | c | h |
] 6 | d | f |
7 | 7||
l | h | |
が望むoutput: | ||
gr_id | gr.members | |
a | 1 | (a、c、g、h、l) |
2
(b 、d、f、j)c | 1 | |
---|---|---|
d | (b、d、f、j) | |
3 | (e、k) | |
2 | (b、d、f、j) | |
(a、c、g、h、l) | ||
1 | (a、c、g、h、l) | |
2 | (b、d、f、j) | |
&&] | k3 | (e、k) |
l | 1 | |
i | 4 | (i) |
ソリューション: | ||
cte_idents として ( 識別として識別1を選択します @tから 連合 識別として識別2を選択します @tから )) 、cte_pairs として ( 識別1、識別2を選択します @tから 識別1識別2 連合 識別2を識別1、識別1として識別2として選択します @tから 識別1識別2 )) 、cte_recursive として ( 選択します cast(cte_idents.ident as varchar(8000)) 、識別1 、識別2 、cast( '、'識別1 '、'識別2 '、' as varchar(8000))として識別 、1 lvlとして から cte_pairs cte_idents.ident = cte_pairs.ident1にcte_identsを結合します ユニオンすべて 選択します cte_recursive.anchorident 、cte_pairs.ident1 、cte_pairs.ident2 、cast(cte_recursive.identpath cte_pairs.ident2 '、' as varchar(8000))as identpath 、cte_recursive.lvl 1 as lvl から cte_pairs cte_recursive.ident2 = cte_pairs.ident1の内側結合CTE_RECURSIVE どこ cte_recursive.identpathはcastのようではありません( '%、' cte_pairs.ident2 '、%' as varchar(8000)) )) 、cte_recursionresult として ( Anchorident、Ident1、Ident2を選択します CTE_Recursiveから )) 、CTE_CLEANRESULT として ( Anchorident、Ident1を識別として選択します cte_recursionresultから 連合 Anchorident、Ident2を識別として選択します cte_recursionresultから )) 選択します cte_idents.ident 、ca_data.xml_valueがnullの場合 その後、cte_idents.ident else ca_data.xml_value end as groupmembers 、deense_rank()over(注文 ca_data.xml_valueがnullの場合 その後、cte_idents.ident else ca_data.xml_value end )GroupIDとして から cte_idents クロス適用 ( cte_cleanresult.ident '、'を選択します CTE_CLEANRESULTから ここで、cte_cleanresult.anchorident = cte_idents.ident XMLパス( '')のcte_cleanresult.identによる注文、タイプ )ca_xml(xml_value) クロス適用 ( ca_xml.xml_value.value( '。'、 'nvarchar(max)'を選択します) )ca_data(xml_value) どこ cte_idents.identはnullではありません 識別による注文; | サンプルoutput: | |
識別子 | gr_id |
a
1
WITH
CTE_Idents
AS
(
SELECT Ident1 AS Ident
FROM @T
UNION
SELECT Ident2 AS Ident
FROM @T
)
,CTE_Pairs
AS
(
SELECT Ident1, Ident2
FROM @T
WHERE Ident1 <> Ident2
UNION
SELECT Ident2 AS Ident1, Ident1 AS Ident2
FROM @T
WHERE Ident1 <> Ident2
)
,CTE_Recursive
AS
(
SELECT
CAST(CTE_Idents.Ident AS varchar(8000)) AS AnchorIdent
, Ident1
, Ident2
, CAST(',' Ident1 ',' Ident2 ',' AS varchar(8000)) AS IdentPath
, 1 AS Lvl
FROM
CTE_Pairs
INNER JOIN CTE_Idents ON CTE_Idents.Ident = CTE_Pairs.Ident1
UNION ALL
SELECT
CTE_Recursive.AnchorIdent
, CTE_Pairs.Ident1
, CTE_Pairs.Ident2
, CAST(CTE_Recursive.IdentPath CTE_Pairs.Ident2 ',' AS varchar(8000)) AS IdentPath
, CTE_Recursive.Lvl 1 AS Lvl
FROM
CTE_Pairs
INNER JOIN CTE_Recursive ON CTE_Recursive.Ident2 = CTE_Pairs.Ident1
WHERE
CTE_Recursive.IdentPath NOT LIKE CAST('%,' CTE_Pairs.Ident2 ',%' AS varchar(8000))
)
,CTE_RecursionResult
AS
(
SELECT AnchorIdent, Ident1, Ident2
FROM CTE_Recursive
)
,CTE_CleanResult
AS
(
SELECT AnchorIdent, Ident1 AS Ident
FROM CTE_RecursionResult
UNION
SELECT AnchorIdent, Ident2 AS Ident
FROM CTE_RecursionResult
)
SELECT
CTE_Idents.Ident
,CASE WHEN CA_Data.XML_Value IS NULL
THEN CTE_Idents.Ident ELSE CA_Data.XML_Value END AS GroupMembers
,DENSE_RANK() OVER(ORDER BY
CASE WHEN CA_Data.XML_Value IS NULL
THEN CTE_Idents.Ident ELSE CA_Data.XML_Value END
) AS GroupID
FROM
CTE_Idents
CROSS APPLY
(
SELECT CTE_CleanResult.Ident ','
FROM CTE_CleanResult
WHERE CTE_CleanResult.AnchorIdent = CTE_Idents.Ident
ORDER BY CTE_CleanResult.Ident FOR XML PATH(''), TYPE
) AS CA_XML(XML_Value)
CROSS APPLY
(
SELECT CA_XML.XML_Value.value('.', 'NVARCHAR(MAX)')
) AS CA_Data(XML_Value)
WHERE
CTE_Idents.Ident IS NOT NULL
ORDER BY Ident;
b
c | 1 | |
---|---|---|
d | 2 | |
e | 3 | (e、k) |
f | 2 | (b、d、f、j) |
k | 3 | |
l | ||
z | 5 | |
クエリは再帰CTEを使用して、CTE_PAIRSテーブルで定義されているエッジに従うグラフ内のすべてのパスを見つけます。 XMLパスとクロスの場合、各グループの接続された識別子を連結するために適用します。 |
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3