T-SQL Dynamic GROUP BY с использованием @parameters - PullRequest
2 голосов
/ 25 июля 2011

Я бы хотел достичь

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 ]

5 голосов
/ 25 июля 2011

Динамический SQL - единственный путь.Однако, какая у вас таблица, где есть множество необязательных группирующих столбцов?

1 голос
/ 25 июля 2011

Прежде всего t.field1 также должен быть в вашей группе или обрабатываться в SQL с помощью функции агрегирования, такой как min или max

Вот немного динамического 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)
0 голосов
/ 25 июля 2011

Я смело предполагаю, что ваши параметры содержат имена ваших полей.В противном случае я не вижу причин, по которым они у вас будут.

Если сгруппированные элементы содержат точно такие же значения внутри групп , вы можете обойтись без группировки, используямин или макс, как это:

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, этоработает и может сочетаться с философией «Мин / Макс», приведенной выше, если вы хотите избавиться от группы с помощью утверждений:

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
  • Создать несколько процедур
  • Использовать операторы

Все зависит от того, как вы собираетесь его использовать.

0 голосов
/ 25 июля 2011

Зачем вам нужно группировать по значениям, которые вы явно передаете в свой запрос?

Исключите @ param1 / 2/3 из оператора выбора, удалите группу с помощью и просто сделайте обычный выбор. В своем коде добавьте свои параметры к тому, что ожидает результатов. В противном случае вы просто создаете сетевой трафик.

...