JNK*_*JNK 5 xml sql-server sql-server-2008-r2
我需要构建一个带有父记录和 1..N 个相关子记录的 XML 包。
子记录是父节点下的一个节点,每个父节点可能有一个或多个子记录。在同一个查询中也可以有多个父项。
上面的查询我没有问题。
我还要求为每条记录(父项和子项)提供一个唯一的基于 0 的索引。我可以ROW_NUMBER为每个子查询使用 with ,但无法找到一种方法来为整个查询中的每条记录获取唯一索引。
(请注意,SQLFiddle 不会以非常易于阅读的格式显示 XML,因此您可能希望在本地 SSMS 中运行它。)
工作SSMS代码如下:
BEGIN TRY
DROP TABLE #Child
DROP TABLE #Parent
END TRY
BEGIN CATCH
END CATCH
CREATE TABLE #Parent
(RecId int PRIMARY KEY NOT NULL,
PersonName varchar(100), Age int)
CREATE TABLE #Child
(ChildID int identity PRIMARY KEY NOT NULL,
ParentRecId int FOREIGN KEY REFERENCES #Parent(RecId),
SalesAmt money)
INSERT INTO #Parent
(RecID, PersonName, Age)
VALUES
(1, 'Aaron Bertrand', 99),
(2, 'Paul White', 20),
(3, 'JNK', 33)
INSERT INTO #Child
(ParentRecID, SalesAmt)
VALUES
(1, 10.00),
(1, 20.00),
(2, 15.15),
(2, 100.00),
(3, 0.00)
SELECT
RecId as 'RID',
PersonName as 'PNAM',
Age,
(
SELECT
C.SalesAmt as 'SAMT',
(ROW_NUMBER() OVER (ORDER BY ParentRecId) - 1) as 'Index'
FROM
#Child C
WHERE
C.ParentRecId = P.RecId
FOR XML PATH ('ChildRec'), ROOT ('ChildRecs'), TYPE
)
FROM
#Parent P
FOR XML PATH ('Parent'), ROOT ('Parents'), TYPE
Run Code Online (Sandbox Code Playgroud)
如何获取此 XML 包的所有父记录和子记录的唯一索引?
我找到了答案 - 我需要创建一个CTE使用所有子记录和父记录的并集并创建一个ROW_NUMBER(),然后JOIN创建一个CTE以获得ROW_NUMBER()在所有记录中唯一的值。
粘贴到 SSMS 的完整解决方案:
BEGIN TRY
DROP TABLE #Child
DROP TABLE #Parent
END TRY
BEGIN CATCH
END CATCH
CREATE TABLE #Parent
(RecId int PRIMARY KEY NOT NULL,
PersonName varchar(100), Age int)
CREATE TABLE #Child
(ChildID int identity PRIMARY KEY NOT NULL,
ParentRecId int FOREIGN KEY REFERENCES #Parent(RecId),
SalesAmt money)
INSERT INTO #Parent
(RecID, PersonName, Age)
VALUES
(1, 'Aaron Bertrand', 99),
(2, 'Paul White', 20),
(3, 'JNK', 33)
INSERT INTO #Child
(ParentRecID, SalesAmt)
VALUES
(1, 10.00),
(1, 20.00),
(2, 15.15),
(2, 100.00),
(3, 0.00)
;WITH IDs AS
(
SELECT
RN = (ROW_NUMBER() OVER (ORDER BY RecId,CASE WHEN ChildId IS NULL THEN 0 ELSE 1 END) -1),
RecId,
ChildId
FROM
(
SELECT
RecId, ChildId = NULL
FROM
#Parent
UNION ALL
SELECT
RecId, ChildId
FROM
#Parent P
INNER JOIN
#Child C
ON C.ParentRecId = P.RecId) x
)
SELECT
P.RecId as 'RID',
P.PersonName as 'PNAM',
P.Age,
I.RN as 'Index',
(
SELECT
C.SalesAmt as 'SAMT',
I.RN as 'Index'
FROM
#Child C
INNER JOIN
IDs I
ON I.ChildId = C.ChildID
WHERE
C.ParentRecId = P.RecId
FOR XML PATH ('ChildRec'), ROOT ('ChildRecs'), TYPE
)
FROM
#Parent P
INNER JOIN
IDs I
ON I.RecId = P.RecId
AND I.ChildId IS NULL
FOR XML PATH ('Parent'), ROOT ('Parents'), TYPE
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
671 次 |
| 最近记录: |