使用@parameters的T-SQL Dynamic GROUP BY

时间:2011-07-25 01:48:00

标签: sql sql-server tsql group-by

我想实现

SELECT @param1, @param2, @param3, t.field1, sum(t.amount)
FROM table t
WHERE t.field 2 IS NOT NULL AND
t.field3ID = '12345'
GROUP BY @param1, @param2, @param3

最好的方法是什么?构建动态SQL是可行的方法吗?

4 个答案:

答案 0 :(得分:5)

动态SQL是唯一的方法。但是,如果你有一堆可选的分组列,你有什么样的表?

答案 1 :(得分:1)

首先,t.field1也应该在你的小组中,或者在sql中使用诸如min或max之类的aggrigate函数进行处理

这里有一些你可以使用的动态sql。它允许您使用不同数量的参数

DECLARE @t TABLE (COLUMNNAME varchar(15))
DECLARE @pstring VARCHAR(1000), @sqlstring varchar(5000)

DECLARE @param1 VARCHAR(15)
DECLARE @param2 VARCHAR(15)
DECLARE @param3 VARCHAR(15)
--declare more columns here

SET @param1 = <colname> -- replace this <colname>
SET @param2 = <colname>
SET @param3 = <colname>
--set the name of the column

INSERT @t SELECT @param1 
UNION ALL SELECT @param2
UNION ALL SELECT @param3
--union all select @param4 etc

SELECT @pstring = COALESCE(@pstring, '') + columnname+',' FROM @t

SET @sqlstring = 'SELECT '+@pstring + 'min(t.field1) field1, sum(t.amount)
FROM table t
WHERE t.field2 IS NOT NULL AND
t.field3ID = ''12345''
GROUP BY ' +stuff(@pstring,len(@pstring), 1,'')

EXEC(@sqlstring)

答案 2 :(得分:0)

为什么需要按显式传入查询的值进行分组?

从select语句中消除@ param1 / 2/3,消除组,然后进行常规选择。在您的代码中,将您的参数添加到期望结果的任何内容中。否则,您只是在创建网络流量。

答案 3 :(得分:0)

我大胆地假设你的参数持有你的字段名称。否则,我认为你没有理由在那里拥有它们。

如果分组的项目中包含完全相同的值,则可以不使用min或max进行分组,如下所示:

SELECT Min(@param1), Min(@param2), Min(@param3), t.field1, sum(t.amount)
FROM table t
WHERE t.field 2 IS NOT NULL AND
t.field3ID = '12345'

您仍然会遇到无法像那样选择字段的问题。

你可以使用case语句,如果你想摆脱group by语句,它可以和上面的“Min / Max”理念结合使用:

SELECT 
    case 
        when @param1 = 'colname1' then colname1
        when @param1 = 'colname2' then colname2
        when @param1 = 'colname2' then colname3
        else null
    end, 
    case 
        when @param2 = 'colname1' then colname1
        when @param2 = 'colname2' then colname2
        when @param2 = 'colname2' then colname3
        else null
    end, 
    case 
        when @param3 = 'colname1' then colname1
        when @param3 = 'colname2' then colname2
        when @param3 = 'colname2' then colname3
        else null
    end, 
    t.field1, 
    sum(t.amount)
FROM table t
WHERE t.field2 IS NOT NULL AND
t.field3ID = '12345'
GROUP BY 
    case 
        when @param1 = 'colname1' then colname1
        when @param1 = 'colname2' then colname2
        when @param1 = 'colname2' then colname3
        else null
    end, 
    case 
        when @param2 = 'colname1' then colname1
        when @param2 = 'colname2' then colname2
        when @param2 = 'colname2' then colname3
        else null
    end, 
    case 
        when @param3 = 'colname1' then colname1
        when @param3 = 'colname2' then colname2
        when @param3 = 'colname2' then colname3
        else null
    end,
    t.field1

我认为您可以选择以下解决方案:

  • 在客户端选择所有必填字段和过滤字段
  • 使用动态SQL
  • 创建多个程序
  • 用例陈述

这完全取决于你将如何使用它。