我在 SQL Server 中有两个表:
产品:包含产品详细信息(ID、产品名称...)。
产品ID | 产品名称 |
---|---|
1 | 产品A |
2 | 产品B |
ProductEan:包含每个产品的多个代码(ID、ProductID、Ean)。
产品ID | 伊恩 |
---|---|
1 | 123456789012 |
1 | 987654321098 |
2 | 111111111111 |
目标是将每个产品的所有 EAN 值聚合到一行中,并将 EAN 连接成单个字符串,并用逗号分隔。
期望的结果:
产品ID | 产品名称 | 伊恩斯 |
---|---|---|
1 | 产品A | 123456789012,987654321098 |
2 | 产品B | 111111111111 |
我目前正在使用以下查询:
SELECT
p.ProductID,
p.ProductName,
STUFF((
SELECT ',' + pe.Ean
FROM ProductEan pe
WHERE pe.ProductID = p.ProductID
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS Eans
FROM
Product p;
+ some JOIN to other tables
但是,此查询存在性能问题,因为 ProductEan 表有超过 300,000 行。执行起来需要很长时间。
我还尝试使用CROSS APPLY来避免相关子查询,如下所示:
SELECT
p.ProductID,
p.ProductName,
e.Eans
FROM
Product p
CROSS APPLY (
SELECT
STUFF((
SELECT ',' + pe.Ean
FROM ProductEan pe
WHERE pe.ProductID = p.ProductID
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS Eans
) e;
+ some JOIN to other tables
虽然这稍微简化了查询结构,但并没有显着提高性能。
如何针对大型数据集优化此聚合?
如何针对大型数据集优化此聚合?
尝试将
./text())[1]
指定为 xquery 表达式,如下例所示。这可以帮助优化大型数据集的 XML 连接方法,如此答案中所述。
至于这是否会提高查询的性能还取决于影响整体执行计划的许多其他因素。
SELECT
p.ProductID,
p.ProductName,
e.Eans
FROM
Product p
CROSS APPLY (
SELECT
STUFF((
SELECT ',' + pe.Ean
FROM ProductEan pe
WHERE pe.ProductID = p.ProductID
FOR XML PATH(''), TYPE).value('(./text())[1]', 'NVARCHAR(MAX)'), 1, 1, '') AS Eans
) e;