Reputation: 1721
Context: I have an SSRS report with a multi-value parameter. The report passes the multi-value parameter to a stored procedure that assigns it to a variable of an nvarchar type. This variable contains unique IDs that map to values in the DB that are actually stored as an int data type.
Details: Basically I need to a) Modify the ssrs report to allow for multi-value entry (which i've already done) b) split_string the nvarchar variable into consumable int type pieces c) process the query with these pieces d) re-construct the string to present the query results in a concatenated fashion per user requirements
Questions: Can you please assist in finding the most efficient way to perform these transformations in the proc I've (attempted) to draft below?
Side note: While I've found some posts related to handling multi-value ssrs parameters in procs here, here and here -- they aren't fixes that apply to my specific scenario given the multiple rounds of transformation needed.
/*This is the parameter supplied by the SSRS report that needs to be split, just declared here for commentary purposes
DECLARE @p_catalog_id nvarchar(max);
SET @p_catalog_id = '163650,163651,163652,163653,163654,163655,163656,163657,310415';
*/
BEGIN
WITH EPV_IDs
AS
(
SELECT h.CATALOG_ID,
h.PARENT_Catalog_ID as 'Series Collection ID',
c.catalog_template as Template,
d.CATALOG_ID as 'EPV ID'
FROM [RDW_DIV38].[dbo].[Catalog_LINK_Catalog] as h
inner join [RDW_DIV38].[dbo].[Catalog] as c on c.Catalog_ID = h.CATALOG_ID
left join [RDW_DIV38].[dbo].[Catalog_LINK_Catalog] as d on d.PARENT_Catalog_ID = h.PARENT_Catalog_ID
inner join [RDW_DIV38].[dbo].[Catalog] as f on f.catalog_id=H.PARENT_Catalog_ID
WHERE c.catalog_template = 'Episode Version'
and f.catalog_template='series Collection'
and c.Catalog_STATUS not in ('Withdrawn', 'Cancelled')
and f.Catalog_STATUS not in ('Withdrawn', 'Cancelled')
and d.Catalog_ID = @p_catalog_id
),
X
AS
(
SELECT EPV_IDs.[Series Collection ID],
EPV_IDs.[Template],
EPV_IDs.[EPV ID],
COUNT(EPV_IDs.[EPV ID])as 'All EPVs'
FROM EPV_IDs
GROUP BY EPV_IDs.[Series Collection ID], EPV_IDs.[Template], EPV_IDs.[EPV ID]
),
y
AS
(
SELECT X.[Series Collection ID],
X.[Template],
case when COUNT(X.[EPV ID]) = X.[All EPVs] Then 'Yes' Else 'No' ENd as 'Full?',
COUNT(X.[EPV ID]) as 'EPVs Found',
X.[All EPVs],STRING_AGG(X.[EPV ID],',')as 'EPV IDs'
FROM X
GROUP BY X.[Series Collection ID] ,X.[Template],x.[All EPVs]
),
A
AS
(
SELECT x.[EPV ID],
y.[Series Collection ID],
y.[Template],
STRING_AGG(y.[Full?],'/')as [Full?],
y.[EPVs Found],
y.[All EPVs],
y.[EPV IDs]
FROM y
inner join x on x.[Series Collection ID]=y.[Series Collection ID]
GROUP BY x.[EPV ID], y.[Series Collection ID], y.[Template], y.[EPVs Found], y.[All EPVs], y.[EPV IDs]
)
SELECT DISTINCT a3.[Series Collection ID] as Series_Collection_ID,
a3.[Template],
a.[Full?] as [Full],
a3.[EPVs Found] as EPVs_Found,
a3.[All EPVs] as All_EPVs,
a3.[EPV IDs] as EPV_IDs
FROM a
left join a as a3 on a3.[EPV ID]=a.[EPV ID]
WHERE not exists (
SELECT 1
FROM a a2
WHERE a2.[EPV ID] =a.[EPV ID] and a2.[Full?] = 'Yes'
)
UNION
SELECT a.[Series Collection ID] as Series_Collection_ID,
a.[Template],
a.[Full?] as [Full],
a.[EPVs Found] as EPVs_Found,
a.[All EPVs] as All_EPVs,
a.[EPV IDs] as EPV_IDs
FROM a
WHERE a.[Full?]='Yes'
END
Upvotes: 2
Views: 1730
Reputation: 1181
if your database is 2016 then you can just use string_split: Replace
and d.Catalog_ID = @p_catalog_id
with
and CAST(d.Catalog_ID as varchar(10)) IN (SELECT value FROM STRING_SPLIT(@p_catalog_id, ',')
Otherwise i'd suggest you use the FOR XML PATH approach - lots of egs out there & others too: https://sqlperformance.com/2012/07/t-sql-queries/split-strings
Upvotes: 2