2015-07-16 7 views
2

Я пытаюсь добавить текущие итоги в таблицу, при значении NULL общая сумма должна быть NULL. Однако SUM игнорирует значения NULL.T-SQL Не игнорировать значения NULL в SUM

Есть ли способ не игнорировать NULL в SUM?

SELECT 
    run_key, 
    time_empty, 
    SUM(time_empty) OVER (PARTITION BY col1, col2 ORDER BY run_key ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as time_empty_rt 
FROM 
    tblmytable 
ORDER BY 
    run_key 

enter image description here

+0

Предоставить образец данных, что вы выбрать и проверить мой ответ. –

ответ

2

Вы можете создать раздел для каждой группы, который имеет такое же количество предшествующих столбцов null.

select run_key 
,  time_empty 
,  sum(time_empty) over (
      partition by preceding_nulls 
      order by run_key 
      rows between unbounded preceding and current row) as time_emtpy_rt 
from (
     select sum(case when time_empty is null then 1 else 0 end) over (
        order by run_key 
        rows between unbounded preceding and current row) as preceding_nulls 
     ,  * 
     from YourTable yt 
     ) sub 

Example at SQL Fiddle.

+0

Чистый и рабочий, ти! – phicon

2

я не могу видеть в любом случае, чтобы приблизиться к этому, кроме как в два этапа, сначала в качестве gaps and islands problem определить ваши острова, чтобы подвести итог, то, чтобы сделать сумму. Так первые острова:

DECLARE @T TABLE (run_key INT, time_empty INT, Col1 INT, Col2 INT) 
INSERT @T (run_key, time_empty) 
VALUES 
    (1, 637), (2, NULL), (3, NULL), (4, NULL), 
    (5, 2967), (6, 1000), (7, NULL), (8, NULL); 

SELECT run_key, 
     time_empty, 
     IslandID = ROW_NUMBER() OVER(ORDER BY Run_key) - 
        ROW_NUMBER() 
           OVER(PARTITION BY 
             Col1, 
             Col2, 
             CASE WHEN time_empty IS NULL THEN 1 ELSE 0 END 
            ORDER BY Run_key) 
FROM @T 
ORDER BY run_key; 

Что дает:

run_key time_empty IslandID 
------------------------------ 
1  637   0 
2  NULL  1 
3  NULL  1 
4  NULL  1 
5  2967  3 
6  1000  3 
7  NULL  3 
8  NULL  3 

Теперь это дает вам колонку (IslandID), чтобы раздел на который будет правильно сбросить сумму в следующем, не нуль:

DECLARE @T TABLE (run_key INT, time_empty INT, Col1 INT, Col2 INT) 
INSERT @T (run_key, time_empty) 
VALUES 
    (1, 637), (2, NULL), (3, NULL), (4, NULL), 
    (5, 2967), (6, 1000), (7, NULL), (8, NULL); 

SELECT run_key, 
     time_empty, 
     time_empty_rt = CASE WHEN time_empty IS NULL THEN NULL 
          ELSE SUM(time_empty) 
            OVER (PARTITION BY Col1, Col2, IslandID 
              ORDER BY run_key 
              ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 
         END 
FROM ( SELECT run_key, 
        time_empty, 
        Col1, 
        Col2, 
        IslandID = ROW_NUMBER() OVER(ORDER BY Run_key) 
           - ROW_NUMBER() 
              OVER(PARTITION BY 
                Col1, 
                Col2, 
                CASE WHEN time_empty IS NULL THEN 1 ELSE 0 END 
               ORDER BY Run_key) 
      FROM @T 
     ) AS t; 
+2

Это должно сработать. Он полагается на 'run_key', увеличиваясь строго с шагом 1. – Andomar

+0

Вы правы, не знаете, почему я это сделал .... Я заменил' run_key - ROW_NUMBER() ... 'с' ROW_NUMBER() OVER (ORDER BY Run_key) - ROW_NUMBER() ... ', то есть правильный способ сделать пробелы и острова, и это устранило требование увеличить его с шагом 1. Спасибо за головы. – GarethD

 Смежные вопросы

  • Нет связанных вопросов^_^