如何将此PostgreSQL代码转换为SQL Server?
select
countries.title,
(select array_to_json(array_agg(row_to_json(t)))
from postcodes t
where t.country_id = countries.id) as codes
from countries
我最初的问题是我需要选择完整的主表并且每行都包含所有细节。
国家:
id title
1 SLO
2 AUT
邮政编码:
id country_id code title
1 1 1000 Lj
2 1 2000 Mb
3 2 22180 Vi
4 2 22484 De
期望的结果:
1 SLO 1000;Lj|2000;MB
2 AUT 22180;Vi|22484;De
不
1 SLO 1000 Lj
1 SLO 2000 Mb
2 AUT 22180 Vi
2 AUT 22484 De
最好的解决方案是使用FOR JSON,但不幸的是我需要支持2008年或至少2012年。
使用左连接时,所有主数据都会被重复以进行详细计数,但我不想这样做。更糟糕的是,选择所有国家/地区,然后为{for循环中的每个国家/地区post_codes
调用select。
答案 0 :(得分:4)
select countries.title,
STUFF((select '|' + t.code + ';' + t.title
from postcodes t
where t.country_id = countries.id
FOR XML PATH('')
),1,1,'') as codes
from countries
- CAST t.code to VARCHAR,如果它是Number
答案 1 :(得分:0)
试试这个:
Select Main.COUNTRY_ID,c.title,Left(Main.POSTCODES,Len(Main.POSTCODES)-1) As "POSTCODES"
From
(
Select distinct ST2.COUNTRY_ID,
(
Select ST1.CODE+';'+ST1.TITLE + '|' AS [text()]
From dbo.POSTCODES ST1
Where ST1.COUNTRY_ID = ST2.COUNTRY_ID
ORDER BY ST1.COUNTRY_ID
For XML PATH ('')
) [POSTCODES]
From dbo.POSTCODES ST2
) [Main]
inner join countries c on c.id=main.country_id
答案 2 :(得分:0)
使用XML PATH
进行连接可能会增加代码的复杂性。最好实现CLR aggregation function。然后,您可以执行以下操作:
SELECT C.[id]
,C.[title]
,REPLACE([dbo].[Concatenate] (P.[code] + ';' + P.[title]), ',', '|')
FROM @Countries C
INNER JOIN @PostCodes P
ON C.[id] = p.[country_id]
GROUP BY C.[id]
,C.[title];
您可以创建自己的连接聚合版本 - 您可以指定分隔符,顺序等。如果您愿意,我可以向您展示示例。
DECLARE @Countries TABLE
(
[id] TINYINT
,[title] VARCHAR(12)
);
INSERT INTO @Countries ([id], [title])
VALUES (1, 'SLO')
,(2, 'AUT');
DECLARE @PostCodes TABLE
(
[id] TINYINT
,[country_id] TINYINT
,[code] VARCHAR(12)
,[title] VARCHAR(12)
);
INSERT INTO @PostCodes ([id], [country_id], [code], [title])
VALUES (1, 1, 1000, 'Lj')
,(2, 1, 2000, 'Mb')
,(3, 2, 22180, 'Vi')
,(4, 2, 22484, 'De');
SELECT C.[id]
,C.[title]
,REPLACE([dbo].[Concatenate] (P.[code] + ';' + P.[title]), ',', '|')
FROM @Countries C
INNER JOIN @PostCodes P
ON C.[id] = p.[country_id]
GROUP BY C.[id]
,C.[title];