【发布时间】:2021-09-08 02:58:05
【问题描述】:
我需要按一组值以及每组的所有匹配行号/id:s 对表进行分组。此操作必须在 SQL Server 2016 的范围内完成。
假设我有下表(地点):
| ID | Country | City |
|---|---|---|
| 1 | Sweden | Stockholm |
| 2 | Norway | Oslo |
| 3 | Iceland | Reykjavik |
| 4 | Sweden | Stockholm |
我追求的结果(没有大括号,因为 Stack Overflow 认为它是代码,阻止我发布):
| ID | Json |
|---|---|
| 1,4 | "Country":"Sweden","City":"Stockholm" |
| 2 | "Country":"Norway ","City":"Oslo" |
| 3 | "Country":"Iceland ","City":"Reykjavik" |
在 SQL Server 2017 中,可以通过以下方式实现上述结果:
SELECT STRING_AGG(ID) ID, (SELECT Country, City FOR JSON PATH) Json
FROM Places GROUP BY Country, City
我设法使用下面的代码在 SQL Server 2016 中获得了类似的结果。 (但以我的实际数据量和列数,这个解决方案太慢了。)
SELECT DISTINCT Country, City INTO #temp FROM Places
SELECT (SELECT ID From Places WHERE Country = P.Country AND City = P.City FOR JSON PATH) ID,
(SELECT Country, City FOR JSON Path) Json FROM #temp P
有没有更高效的方法来实现我所追求的结果?
编辑:正如人们建议我尝试“FOR XML Path”,我尝试了下面的代码。这会产生以下错误“Places.ID 在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中”:
SELECT stuff((select ',' + cast(ID as varchar(max)) for xml path ('')), 1, 1, '') ID,
(SELECT Country, City FOR JSON PATH) Json
FROM Places GROUP BY Country, City
【问题讨论】:
-
没有SQL Server 2013。请发出
SELECT @@VERSION;并更新问题。 -
在提出问题时,您需要提供minimal reproducible example:(1) DDL 和样本数据填充,即 CREATE 表加上 INSERT、T-SQL 语句。 (2) 你需要做什么,即逻辑,以及你在 T-SQL 中尝试实现它。 (3) 基于上述#1 中的样本数据的期望输出。 (4) 你的 SQL Server 版本 (SELECT @@version;)
-
另外,看起来你实际上想要更像 JSON 输出的东西,试试red-gate.com/simple-talk/sql/learn-sql-server/…
-
那么你所做的实现是不正确的,@Hwende。
FOR XML PATH和STUFF删除前导分隔符,是 2017 年之前的解决方案。 -
该尝试中没有相关的子查询,@Hwende。这就是为什么。分组时需要使用相关子查询。
标签: sql-server group-by string-aggregation