I want to return asset count as per type and also want to concatenate asset ids. I am using FOR XML
and path which works fairly good but as soon as I add where clause, it does not work as expected.
This is my table schema and query:
CREATE TABLE [dbo].[Asset]
(
[AssetSeqNumber] [bigint] NULL,
[AssetType] [varchar](100) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[Asset] ([AssetSeqNumber], [AssetType])
VALUES (1, N'Tree')
INSERT [dbo].[Asset] ([AssetSeqNumber], [AssetType])
VALUES (2, N'Tree')
INSERT [dbo].[Asset] ([AssetSeqNumber], [AssetType])
VALUES (3, N'Tree')
INSERT [dbo].[Asset] ([AssetSeqNumber], [AssetType])
VALUES (4, N'Barbecue')
INSERT [dbo].[Asset] ([AssetSeqNumber], [AssetType])
VALUES (5, N'Bridge')
INSERT [dbo].[Asset] ([AssetSeqNumber], [AssetType])
VALUES (101, N'Tree')
INSERT [dbo].[Asset] ([AssetSeqNumber], [AssetType])
VALUES (102, N'Tree')
GO
Query:
SELECT
AssetType,
COUNT(AssetSeqNumber) AS count,
STUFF((SELECT DISTINCT ',' + CAST(AssetSeqNumber AS varchar(100))
FROM Asset
WHERE AssetType = a.AssetType
FOR XML PATH ('')), 1, 1, '') AS AssetIds
FROM
Asset AS a
WHERE
a.AssetSeqNumber IN (1, 2, 3, 4, 5)
GROUP BY
AssetType
This query return result for ids which are not in the where condition (i.e. 101,102). I understand it is because inner query check asset types but I can't figure out how to show expected result.
Note: I am using SQL Server 2019 (v15.0.2095.3 (X64))
You need to modify the where clause for the select statement inside the STUFF
function as the following:
WHERE AssetType = a.AssetType AND AssetSeqNumber IN (1, 2, 3, 4, 5)
Also, for your version of SQL Server, you could simplify this by using STRING_AGG
function as the following:
SELECT AssetType,
COUNT(*) [Count],
STRING_AGG(AssetSeqNumber, ',') AssetIds
FROM Asset
WHERE AssetSeqNumber IN (1, 2, 3, 4, 5)
GROUP BY AssetType
See a demo for both queries.