2015-10-01 6 views
2

я в следующей таблице, которые представляют клиентов для каждого дня:SQL сумма по перегородке за предыдущий период

+----------+-----------+ 
| Date | Customers | 
+----------+-----------+ 
| 1/1/2014 |   4 | 
| 1/2/2014 |   7 | 
| 1/3/2014 |   5 | 
| 1/4/2014 |   5 | 
| 1/5/2014 |  10 | 
| 2/1/2014 |   7 | 
| 2/2/2014 |   4 | 
| 2/3/2014 |   1 | 
| 2/4/2014 |   5 | 
+----------+-----------+ 

Я хотел бы добавить еще 2 колонки:

  1. Резюме клиентов для текущий месяц
  2. Резюме клиентов за предыдущий месяц

вот желаемый результат:

+----------+-----------+----------------------+------------------------+ 
| Date | Customers | Sum_of_Current_month | Sum_of_Preceding_month | 
+----------+-----------+----------------------+------------------------+ 
| 1/1/2014 |   4 |     31 |      0 | 
| 1/2/2014 |   7 |     31 |      0 | 
| 1/3/2014 |   5 |     31 |      0 | 
| 1/4/2014 |   5 |     31 |      0 | 
| 1/5/2014 |  10 |     31 |      0 | 
| 2/1/2014 |   7 |     17 |      31 | 
| 2/2/2014 |   4 |     17 |      31 | 
| 2/3/2014 |   1 |     17 |      31 | 
| 2/4/2014 |   5 |     17 |      31 | 
+----------+-----------+----------------------+------------------------+ 

мне удалось вычислить 3-й столбец с помощью простой суммы по статсумме:

Select 
    Date, 
    Customers, 
    Sum(Customers) over (Partition by (Month(Date)||year(Date) Order by 1) as Sum_of_Current_month 
From table 

Однако, я не могу найти способ, чтобы вычислить Sum_of_preceding_month колонка.

Цените свою поддержку.

Асаф

+0

Для этого случая я хотел бы иметь значение 0. –

+0

Отправляй сообщение. Похоже на ту же тему. http://stackoverflow.com/questions/8124756/teradata-equivalent-for-lead-and-lag-function-of-oracle –

ответ

0

Я думаю, что это может быть проще с помощью lag() и агрегации подзапрос. Синтаксис ANSI стандарт:

Select t.*, tt.sumCustomers, tt.prev_sumCustomers 
From table t join 
    (select extract(year from date) as yyyy, extract(month from date) as mm, 
      sum(Customers) as sumCustomers, 
      lag(sum(Customers)) over (order by extract(year from date), extract(month from date) 
            ) as prev_sumCustomers 
     from table t 
     group by extract(year from date), extract(month from date) 
    ) tt 
    on extract(year from date) = tt.yyyy and extract(month from date) = t.mm; 

В Teradata, это было бы записать так:

Select t.*, tt.sumCustomers, tt.prev_sumCustomers 
From table t join 
    (select extract(year from date) as yyyy, extract(month from date) as mm, 
      sum(Customers) as sumCustomers, 
      min(sum(Customers)) over (order by extract(year from date), extract(month from date) 
             rows between 1 preceding and 1 preceding 
            ) as prev_sumCustomers 
     from table t 
     group by extract(year from date), extract(month from date) 
    ) tt 
    on extract(year from date) = tt.yyyy and extract(month from date) = t.mm; 
+0

Я не верю, что Teradata уже реализовала поддержку LAG. Я полагаю, что он полагается на предложения ROWS PRECEDING и ROWS FOLLOWING в функции окна OVER() для выполнения LEAD и LAG. –

+0

Спасибо, Гордон и Роб. Я верю, что Роб прав. Любая идея, как это может быть достигнуто с синтаксисом «rows before»? –

+0

См. Ниже ответ @dnoeth. –

0

Попробуйте это:

SELECT 
    [Date], 
    [Customers], 
    (SELECT SUM(customers) FROM table WHERE MONTH(dte) = MONTH(tbl.dte)), 
    ISNULL((SELECT SUM(customers) FROM table WHERE MONTH(dte) = MONTH(DATEADD(MONTH, -1, tbl.dte))), 0) 
FROM table tbl 
+1

Я не это, это синтаксис Teradata. –

2

В прошлом месяце немного сложнее. Какой у вас релиз Teradata, TD14.10 поддерживает LAST_VALUE:

SELECT 
    dt, 
    customers, 
    Sum_of_Current_month, 
    -- return the previous sum 
    COALESCE(LAST_VALUE(x ignore NULLS) 
      OVER (ORDER BY dt 
        ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) 
      ,0) AS Sum_of_Preceding_month 
FROM 
(
    SELECT 
    dt, 
    Customers, 
    SUM(Customers) OVER (PARTITION BY TRUNC(dt,'mon')) AS Sum_of_Current_month, 
    CASE -- keep the number only for the last day in month 
     WHEN ROW_NUMBER() 
      OVER (PARTITION BY TRUNC(dt,'mon') 
        ORDER BY dt) 
      = COUNT(*) 
      OVER (PARTITION BY TRUNC(dt,'mon')) 
     THEN Sum_of_Current_month 
    END AS x 
    FROM tab 
) AS dt 
+0

Это прекрасно работает. Благодаря! –

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