Teradata中的SQL特殊组

时间:2017-11-18 18:14:43

标签: sql teradata

我在表格中有这些数据:

service | vat | ini_date | end_date
  1        A   10/01/2017 31/01/2017
  2        A   15/01/2017 28/02/2017
  3        A   15/02/2017 31/03/2017
  4        B   15/01/2017 31/03/2017
  5        B   15/02/2017 31/03/2017
  6        B   20/04/2017 31/05/2017
  7        B   20/05/2017 31/05/2017

我必须按时匹配增值税服务。

我的输出应该是这样的:

group service | vat | ini_date | end_date
  1    1        A   10/01/2017 31/01/2017
  1    2        A   15/01/2017 28/02/2017
  1    3        A   15/02/2017 31/03/2017
  1    4        B   15/01/2017 31/03/2017
  1    5        B   15/02/2017 31/03/2017
  2    6        B   20/04/2017 31/05/2017
  2    7        B   20/05/2017 31/05/2017

我不能使用程序,我正在尝试一些分析功能,但有很多的语法。当您有三个以上的服务在时间上分别重合时,问题就开始了。

欢迎任何想法。 谢谢:))

2 个答案:

答案 0 :(得分:0)

似乎你为每个“块”时间递增,所以必须检测日期中的“间隙”。下面我使用了一个Postgres小提琴,使用窗口函数LEAD()来发现是否存在间隙,然后使用DENSE_RANK()将其排列到最终输出中。在第二个cte“common_dates”中,相关子查询用于定位检测到下一个间隙的日期。然后,此信息用于订购最终DENSE_RANK()在Teradata中执行此子查询可能有一种更有效的方法,但我无法对其进行试验。

NB:我假设“服务”可以用于LEAD()函数和相关子查询中的排序。

注意:“group”不是我推荐的列名,所以我使用了“group_num”而我扩展了样本数据来测试查询。

Demo(PostgreSQL 9.6)

CREATE TABLE Table1
    ("service" int, "vat" varchar(1), "ini_date" date, "end_date" date)
;

INSERT INTO Table1
    ("service", "vat", "ini_date", "end_date")
VALUES
    (11, 'A', '2016-01-10 00:00:00', '2016-01-31 00:00:00'),
    (21, 'A', '2016-01-15 00:00:00', '2016-02-28 00:00:00'),
    (31, 'A', '2016-02-15 00:00:00', '2016-03-31 00:00:00'),
    (41, 'B', '2016-01-15 00:00:00', '2016-03-31 00:00:00'),
    (51, 'B', '2016-02-15 00:00:00', '2016-03-31 00:00:00'),
    (61, 'B', '2016-04-20 00:00:00', '2016-05-31 00:00:00'),
    (71, 'B', '2016-05-20 00:00:00', '2016-05-31 00:00:00'),

    (91, 'A', '2017-01-10 00:00:00', '2017-01-31 00:00:00'),
    (92, 'A', '2017-01-15 00:00:00', '2017-02-28 00:00:00'),
    (93, 'A', '2017-02-15 00:00:00', '2017-03-31 00:00:00'),
    (94, 'B', '2017-01-15 00:00:00', '2017-03-31 00:00:00'),
    (95, 'B', '2017-02-15 00:00:00', '2017-03-31 00:00:00'),
    (96, 'B', '2017-04-20 00:00:00', '2017-05-31 00:00:00'),
    (97, 'B', '2017-05-20 00:00:00', '2017-05-31 00:00:00')
;

查询1

with gapflag as (
      SELECT
        *
      , lag(end_date) over(order by service) - ini_date dfdts
      , max(end_date) over() max_date
      FROM Table1
      )  
, common_dates as (     
      select
        *
        , coalesce(
                (select ini_date 
                 from gapflag t2 
                 where t2.dfdts < 1  and t2.service > gapflag.service
                 order by service limit 1)
              , 
                max_date
            ) grp_date
      from gapflag
   )
select
       dense_rank() over(order by grp_date) group_num
     , service, vat, ini_date, end_date
from common_dates

<强> Results

| group_num | service | vat |   ini_date |   end_date |
|-----------|---------|-----|------------|------------|
|         1 |      11 |   A | 2016-01-10 | 2016-01-31 |
|         1 |      21 |   A | 2016-01-15 | 2016-02-28 |
|         1 |      31 |   A | 2016-02-15 | 2016-03-31 |
|         1 |      41 |   B | 2016-01-15 | 2016-03-31 |
|         1 |      51 |   B | 2016-02-15 | 2016-03-31 |
|         2 |      61 |   B | 2016-04-20 | 2016-05-31 |
|         2 |      71 |   B | 2016-05-20 | 2016-05-31 |
|         3 |      91 |   A | 2017-01-10 | 2017-01-31 |
|         3 |      92 |   A | 2017-01-15 | 2017-02-28 |
|         3 |      93 |   A | 2017-02-15 | 2017-03-31 |
|         3 |      94 |   B | 2017-01-15 | 2017-03-31 |
|         3 |      95 |   B | 2017-02-15 | 2017-03-31 |
|         4 |      96 |   B | 2017-04-20 | 2017-05-31 |
|         4 |      97 |   B | 2017-05-20 | 2017-05-31 |

答案 1 :(得分:0)

您希望将按时间重叠的服务分组到组中。由于服务1-5全部重叠(如链),因此它们变为“组1”。由于下一个服务(服务6)与前一个组不重叠,因此您可以为其指定下一个ID - “组2”并继续。那是对的吗?

如果是这样......一些可以帮助你的功能:

窗口功能(查看前一行)
PERIOD数据类型+测试重叠的相关函数