我需要从我的表中生成如下格式的 XML。你能建议我应该使用什么方法(路径、元素、原始)或者可以是几种方法的组合吗?
请在下面找到我的测试数据和我刚刚开始的一些代码。另请参阅具有大量嵌套的请求的 XML 格式。这可以在一个
SELECT
中完成吗?或者我可以按级别组合多个部分吗?
SELECT * INTO #t FROM (
SELECT 2020 yy, 'Alpha' CompanyName,
'BossA' FirstName_Owner, 'Smith' LastName_Owner, 'John1' FirstName_Client , 'Dow1' LasttName_Client,'Yes' Active union
SELECT 2020 yy, 'Alpha' CompanyName,
'BossA' FirstName_Owner, 'Smith' LastName_Owner, 'Peter2' FirstName_Client , 'Redd2' LasttName_Client,'No' Active UNION
SELECT 2020 yy, 'Alpha' CompanyName,
'BossyBB' FirstName_Owner, 'Green' LastName_Owner, 'Mary' FirstName_Client , 'Robbins3' LasttName_Client,'Yes' Active
)a --- SELECT TOP 100 * FROM #t -- DROP TABLE IF EXISTS #t
SELECT yy, CompanyName
--SELECT
-- FirstName_Owner, LastName_Owner,
-- FirstName_Client , LasttName_Client, Active
FROM #t
FOR XML RAW('CompanyInfo') , ELEMENTS -- Path
--FOR XML RAW('Client'), ROOT ('Clients')
我的测试数据请求以 XML 格式输出:
<GemReport>
<Version>2.0</Version>
<Company>
<CompanyInfo>
<Year>2020</Year>
<CompanyName>Alpha</CompanyName>
<Owners>
<Owner>
<FirstName>John</FirstName>
<LastName>Doe</LastName>
<Clients>
<Client>
<FirstName>John1</FirstName>
<LastName>Doe1</LastName>
<Contract>
<Active>Yes</Active>
</Contract>
</Client>
<Client>
<FirstName>Peter2</FirstName>
<LastName>Redd2</LastName>
<Contract>
<Active>NO</Active>
</Contract>
</Client>
</Clients>
</Owner>
<Owner>
<FirstName>BossyBB</FirstName>
<LastName>Green</LastName>
<Clients>
<Client>
<FirstName>Mary</FirstName>
<LastName>Robbins3</LastName>
<Contract>
<Active>Yes</Active>
</Contract>
</Client>
</Owners>
</CompanyInfo>
</Company>
</GemReport>
由于您的设计是非规范化的,因此您将需要在此处使用一些 self
JOIN
,使用 CTE 来获取公司和公司所有者详细信息的 DISTINCT
值。然后,您可以使用子查询为每个层嵌套 FOR XML PATH
(Owners
和 Clients
)。
最有可能获得具有更大数据集的高性能解决方案,实际上是修复您的设计并将其标准化;那么您不需要多次扫描同一个表,而是可以为公司、所有者和客户创建一个表,每个表都有相关的主/外键约束和索引。
USE Sandbox;
GO
SELECT *
INTO dbo.YourTable
FROM (SELECT 2020 AS yy,
'Alpha' AS CompanyName,
'BossA' AS FirstName_Owner,
'Smith' AS LastName_Owner,
'John1' AS FirstName_Client,
'Dow1' AS LasttName_Client,
'Yes' AS Active
UNION --ALL?
SELECT 2020 AS yy,
'Alpha' AS CompanyName,
'BossA' AS FirstName_Owner,
'Smith' AS LastName_Owner,
'Peter2' AS FirstName_Client,
'Redd2' AS LasttName_Client,
'No' AS Active
UNION --ALL?
SELECT 2020 AS yy,
'Alpha' AS CompanyName,
'BossyBB' AS FirstName_Owner,
'Green' AS LastName_Owner,
'Mary' AS FirstName_Client,
'Robbins3' AS LasttName_Client,
'Yes' AS Active) a;
GO
WITH Companies AS(
SELECT DISTINCT
CompanyName,
yy
FROM dbo.YourTable),
CompanyOwners AS(
SELECT DISTINCT
CompanyName,
yy,
FirstName_Owner,
LastName_Owner
FROM dbo.YourTable)
SELECT 2.0 AS Version,
(SELECT C.yy AS [Year],
C.CompanyName AS [CompanyName],
(SELECT CO.FirstName_Owner AS FirstName,
CO.LastName_Owner AS LastName,
(SELECT YT.FirstName_Client AS FirstName,
YT.LasttName_Client AS LastName,
YT.Active AS [Contract/Active]
FROM dbo.YourTable YT
WHERE YT.yy = CO.yy
AND YT.CompanyName = CO.CompanyName
AND YT.FirstName_Owner = CO.FirstName_Owner --I hope this can't be NULL
AND YT.LastName_Owner = CO.LastName_Owner --I hope this can't be NULL
FOR XML PATH('Client'),ROOT('Clients'),TYPE)
FROM CompanyOwners CO
WHERE CO.yy = C.yy
AND CO.CompanyName = C.CompanyName
FOR XML PATH('Owner'),ROOT('Owners'),TYPE)
FROM Companies C
FOR XML PATH('CompanyInfo'), ROOT('Company'),TYPE)
FOR XML PATH('GemReport')
GO
DROP TABLE dbo.YourTable;
生成以下 XML:
<GemReport>
<Version>2.0</Version>
<Company>
<CompanyInfo>
<Year>2020</Year>
<CompanyName>Alpha</CompanyName>
<Owners>
<Owner>
<FirstName>BossA</FirstName>
<LastName>Smith</LastName>
<Clients>
<Client>
<FirstName>John1</FirstName>
<LastName>Dow1</LastName>
<Contract>
<Active>Yes</Active>
</Contract>
</Client>
<Client>
<FirstName>Peter2</FirstName>
<LastName>Redd2</LastName>
<Contract>
<Active>No</Active>
</Contract>
</Client>
</Clients>
</Owner>
<Owner>
<FirstName>BossyBB</FirstName>
<LastName>Green</LastName>
<Clients>
<Client>
<FirstName>Mary</FirstName>
<LastName>Robbins3</LastName>
<Contract>
<Active>Yes</Active>
</Contract>
</Client>
</Clients>
</Owner>
</Owners>
</CompanyInfo>
</Company>
</GemReport>
注意,这与 OP 所需的 XML 不匹配,因为那不是有效的 XML。最后一个
Clients
和 Owner
节点not 关闭。我以为这是错误的。