上一期间分区上的SQL和

上一期间分区上的SQL和,sql,teradata,Sql,Teradata,我有下表,代表每天的客户: +----------+-----------+ | 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

我有下表,代表每天的客户:

+----------+-----------+
|   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 |
+----------+-----------+
我想再添加两列:

  • 当月客户汇总表
  • 上个月的客户摘要
  • 以下是期望的结果:

    +----------+-----------+----------------------+------------------------+
    |   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 |
    +----------+-----------+----------------------+------------------------+
    
    我已经设法通过简单的分区函数求和来计算第三列:

    Select 
      Date,
      Customers, 
      Sum(Customers) over (Partition by (Month(Date)||year(Date) Order by 1) as Sum_of_Current_month
    From table
    
    但是,我找不到一种方法来计算前一个月列的和

    感谢您的支持


    Asaf

    我认为使用
    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;
    
    试试这个:

     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
    

    上个月有点棘手。您的Teradata版本是什么,TD14.10支持
    LAST\u值

    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的值。看看这篇文章。好像是同一个话题。我不知道这是Teradata语法。我不相信Teradata已经实现了对LAG的支持。我相信它依赖于OVER()窗口函数中的前行和后行子句来完成超前和滞后。谢谢Gordon和Rob。我相信罗布是对的。您知道如何使用“行前置”语法实现这一点吗?请参阅下面的@dnoeth response。TD14.10实现了
    第一个值
    和最后一个值
    ,这是关于
    前置
    滞后的更通用版本`