简体   繁体   中英

Dynamically selecting and grouping by specified parameters in SQL Server

I am trying to create optional parameters in a stored process in which I group by the parameters under certain conditions.

For example:

SELECT
    TP.ProductID,
    case 
        when @passangers='Y'     then (TP.Passangersgroup)
        when @fareclass='Y'      then (TP.Fareclass)
        when @ispriorbooking='Y' then (TP.IsPriorBooking)
    end
INTO ##B
FROM ##A TP
GROUP BY  
    TP.ProductID, 
    case 
        when @passangers='Y'     then (TP.Passangersgroup)
        when @fareclass='Y'      then (TP.Fareclass)
        when @ispriorbooking='Y' then (TP.IsPriorBooking)
    end

In this case, I would be able to select 'Y' for any of the 3 parameters, and I would want to add them to select statement and group by.

Any ideas?

You need to do this with dynamic SQL; something like:

declare @sql varchar(max) = 'SELECT
    TP.ProductID, ' + 
    case when @passangers='Y' then 'TP.Passangersgroup'
    when @fareclass='Y' then 'TP.Fareclass'
    when @ispriorbooking='Y' then 'TP.IsPriorBooking'
else ''        
end
+ ' INTO ##B
FROM ##A TP'
--ETC

Exec(@sql)

If you want to add up to all three columns, you need three case statements:

declare @sql varchar(max) = 'SELECT
    TP.ProductID, ' + 
    case when @passangers='Y' then 'TP.Passangersgroup' else '' end
    + case when @fareclass='Y' then 'TP.Fareclass' else '' end
--ETC.
+ ' INTO ##B
FROM ##A TP'

Dynamic SQL will be the best bet, but I would figure out the column you want and then pass in the one column as a variable. Less likely to suffer SQL injection and more readable.

DECLARE @passangers CHAR(1), @fareclass CHAR(1), @ispriorbooking CHAR(1)
SET @passangers='Y'

DECLARE @SQLCMD NVARCHAR(MAX), @YValue NVARCHAR(1000)

--set the select and group by field
SELECT @YValue=
    case 
        when @passangers='Y' then N'TP.Passangersgroup'
        when @fareclass='Y' then N'TP.Fareclass'
        when @ispriorbooking='Y' then N'TP.IsPriorBooking'
        else NULL
    end

IF @YValue IS NOT NULL
BEGIN
    SET @SQLCMD=N'
    SELECT
    TP.ProductID,'+@YValue+'
    INTO ##B
    FROM ##A TP
    GROUP BY  
        TP.ProductID, '+@YValue

    PRINT @SQLCMD
    --EXEC sp_executesql @SQLCMD
END
ELSE
    PRINT 'INVALID PARAMETER PASSED IN'

You have to use dynamic sql but case statement mentioned in Steve Mangiameli code will not work in case when more than one column is selected as 'Y'. The below code will be working fine for multiple columns selected as 'Y'-

create procedure proc1
@passangers varchar(100) = null,
@fareclass varchar(100) = null,
@ispriorbooking varchar(100) = null
as
begin
declare @sql nvarchar(100)
declare @var varchar(100)

if @passangers = 'y'
set @var = tp.Passangersgroup + ', '
if @fareclass = 'y'
set @var = @var + TP.Fareclass + ', '
if @ispriorbooking = 'y'
set @var = @var + TP.IsPriorBooking


set @sql =  'select ' + @var + ' into ##b from ##a as TP group by  ' + @var + 'option(recomplile)'

exec sp_executesql @sql
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM