我在表格中有这些数据:
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
我不能使用程序,我正在尝试一些分析功能,但有很多的语法。当您有三个以上的服务在时间上分别重合时,问题就开始了。
欢迎任何想法。 谢谢:))
答案 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数据类型+测试重叠的相关函数