Member 14219614 Ответов: 1

Работа с нулями, динамическими столбцами в pivot


Привет, у меня есть нули в наборе данных, который я пытаюсь повернуть с помощью столбца total, и поэтому мой столбец total выходит как null. Мой код выглядит следующим образом

DECLARE @cols       NVARCHAR(MAX)=''
DECLARE @query      NVARCHAR(MAX)=''
DECLARE @COLS_SUM   NVARCHAR(MAX)=''

--Preparing columns for Pivot
SELECT @cols = @cols + QUOTENAME(finmonth) + ',' 
FROM (SELECT DISTINCT finmonth FROM [DATASOURCE] ) AS tmp
SELECT @cols = SUBSTRING(@cols, 0, LEN(@cols))

--Preparing sum of columns for Totals Horizontal
SELECT @COLS_SUM = @COLS_SUM + QUOTENAME(finmonth) + '+' 
FROM (SELECT DISTINCT finmonth FROM [[DATASOURCE] ) AS tmp
SELECT @COLS_SUM = ','+ SUBSTRING(@COLS_SUM, 0, LEN(@COLS_SUM)) +' AS TOTAL'


SET @query = 
            'SELECT *'+@COLS_SUM+'  INTO #TAB FROM 
            (
                    SELECT var1, var2, var3, finmonth, sum(Actual_Activity) as [activity]
  FROM [[DATASOURCE]
  where [FinYear] = ''2018''
    group by  var1, var2, var3, finmonth
            ) src
            PIVOT 
            (
                   SUM([activity])  FOR finmonth IN (' + @cols + ')
            ) piv

            SELECT * FROM #TAB
            

            '

execute(@query)


Вот некоторые примеры фиктивных данных, которые могли бы привести к этой проблеме. Итак, где один Var1 (var1=a ниже) имеет данные для finmonth=2, а другой-нет. Var1 = b будет иметь null для finmonth = 2, так как у них нет данных за этот месяц.
var1	var2	var3	finmonth	Actual_activity
a	b	c	1	20
a	b	c	1	30
a	b	c	1	40
a	b	c	2	10
a	b	c	2	20
a	b	c	2	30
b	b	c	1	1
b	b	c	1	2
b	b	c	1	3


Таблица результатов выглядит так - но Итого для 2-й строки должно быть 6
r1	var2	var3	1	2	Total
a	b	c	90	60	150
b	b	c	6	Null	Null


Что я уже пробовал:

Я пробовал использовать isnull в основной группе по запросу, но, похоже, это не имеет никакого эффекта

CHill60

Некоторые примеры данных были бы неплохо. Вместо того, чтобы показывать нам динамический SQL, почему бы не представить пример фактического SQL, который вызывает у вас проблему - таким образом, нам не нужно пытаться воссоздать так много

Member 14219614

Спасибо за ваш комментарий, я добавил некоторые фиктивные данные, которые привели бы к описанной проблеме. Извините я новичок в динамическом SQL поэтому вопрос может быть сформулирован не очень хорошо

CHill60

Извините, что я не вернулся к вам по этому вопросу, но, по крайней мере, Мацей смог предоставить вам хорошее решение :-)

Gerry Schmitz

Ну, покажите, где / как вы использовали ISNULL, который "кажется" не имеет никакого эффекта.

https://database.guide/how-to-replace-null-with-another-value-in-sql-server-isnull/

Member 14219614

Пожалуйста, смотрите обновленные фиктивные данные и объяснение выше таблицы данных

1 Ответов

Рейтинг:
4

Maciej Los

Статическая версия sql-оператора должна выглядеть следующим образом:

SELECT var1, var2, var3, [1], [2], COALESCE([1], 0) + COALESCE([2], 0) AS Total
FROM (
    SELECT var1, var2, var3, finmonth, Actual_Activity
    FROM YOUR_TABLE
    WHERE FinYear = 2018) AS DT
PIVOT(SUM(Actual_Activity) FOR finmonth IN ([1], [2])) AS PVT


Теперь вам нужно "преобразовать его" в динамическую версию.
Если вы хотите избежать этого NULLв [1] и [2] седла, можно использовать COALESCE метод вокруг них.

Примечание: FinYear и finmonth должны быть числовые поля!

[РЕДАКТИРОВАТЬ]
Если вы хотите получить правильные данные в @COLS_SUM переменная, проверьте это:
SELECT @COLS_SUM = @COLS_SUM + 'COALESCE(' + QUOTENAME(finmonth) + ',0)+' 
FROM (SELECT DISTINCT finmonth FROM YOUR_TABLE ) AS tmp
SELECT @COLS_SUM = ','+ SUBSTRING(@COLS_SUM, 0, LEN(@COLS_SUM)) +' AS TOTAL'


Member 14219614

Спасибо за ваш ответ, я вижу, что у меня была избыточная агрегация в моем запросе, и хорошо бы это исправить. Однако то, что вы предложили, похоже, эквивалентно моему исходному коду в том, что все еще получаете нули в поворотных полях, которые приводят к тому, что столбец общего итога имеет нули.

Чтобы исправить это, оператор select первой строки должен быть SELECT var1, var2, var3, [1], [2], isnull([1],0) + isnull([2],0) в качестве итога

И это действительно суть моего первоначального вопроса - я не знаю, как преобразовать его в динамический формат

Maciej Los

Проверьте обновленный ответ.

Member 14219614

Спасибо Мацей Лос, что теперь отлично работает

Maciej Los

Всегда пожалуйста!

CHill60

5 б

Maciej Los

Спасибо, Кэролайн.