雪花 - 给定开始日期和结束日期列,分解每个月并将该月的天数计算到单独的行中
Snowflake - given a start and end date column, break out each month and count number of days for the month into separate rows
我有下面的 table (dates_table
),其中的行如下所示,例如 start_date
= '2022-01-25' 和 end_date
= '2022-02-04'.
start_date
end_date
2022-01-25
2022-02-04
2018-08-31
2018-10-05
我正在尝试从上面创建一个新的 table 并添加另一列 days_count
,这需要 start_date 1/25,看看有多少天那个月(第一行是 7,因为 1/25、1/26、1/27、1/28、1/29、1/30、1/31),下一行是 4,因为 2/1 是 4 天- 2/4:
month
start_date
end_date
days_count
2022-01-01
2022-01-25
2022-02-04
7
2022-02-01
2022-01-25
2022-02-04
4
2018-08-01
2018-08-31
2018-10-05
1
2018-09-01
2018-08-31
2018-10-05
30
2018-10-01
2018-08-31
2018-10-05
5
您应该添加另一列来指示您正在计算的计数类型,但您可以使用 datediff
、last_day
和 date_trunc
(首先获取月)。这是一个例子
set start_date='2022-01-25'::date;
set end_date='2022-02-04'::date;
select $start_date,
$end_date,
'Start_Remainder' as label,
datediff(day,$start_date,last_day($start_date))+1 as days_count
union all
select $start_date,
$end_date,
'End_Accrued' as label,
datediff(day,date_trunc('month',$end_date),$end_date)+1 as days_count
如果我是你,我会在单独的列中显示计数
select $start_date,
$end_date,
datediff(day,$start_date,last_day($start_date))+1 as Start_Remainder_Days,
datediff(day,date_trunc('month',$end_date),$end_date)+1 as End_Accrued_Days
有一个 CTE 提供数据,还有几个 pre-conditioning CTE
WITH data_table(start_date, end_date) as (
SELECT * from values
('2022-01-25'::date, '2022-02-04'::date),
('2018-08-31'::date, '2018-10-05'::date)
), large_range as (
SELECT row_number() over (order by null)-1 as rn
FROM table(generator(ROWCOUNT => 1000))
), pre_condition as (
SELECT
start_date
,end_date
,datediff('month', start_date, end_date) as m
FROM data_table
)
SELECT
date_trunc('month', dateadd('month', r.rn, d.start_date)) as month
,d.start_date
,d.end_date
,datediff('day', greatest(d.start_date, month), least(d.end_date, dateadd('day', -1, dateadd('month', 1, month))))+1 as days_count
FROM pre_condition as d
JOIN large_range as r ON r.rn <= d.m
ORDER BY d.start_date, month;
给出:
MONTH
START_DATE
END_DATE
DAYS_COUNT
2018-08-01
2018-08-31
2018-10-05
1
2018-09-01
2018-08-31
2018-10-05
30
2018-10-01
2018-08-31
2018-10-05
5
2022-01-01
2022-01-25
2022-02-04
7
2022-02-01
2022-01-25
2022-02-04
4
如果您不喜欢 CTE 的外观
SELECT
date_trunc('month', dateadd('month', r.rn, d.start_date)) as month
,d.start_date
,d.end_date
,datediff('day', greatest(d.start_date, month), least(d.end_date, dateadd('day', -1, dateadd('month', 1, month))))+1 as days_count
FROM (
SELECT
start_date
,end_date
,datediff('month', start_date, end_date) as m
FROM data_table
) as d
JOIN (
SELECT row_number() over (order by null)-1 as rn
FROM table(generator(ROWCOUNT => 1000))
) as r ON r.rn <= d.m
ORDER BY d.start_date, month;
我有下面的 table (dates_table
),其中的行如下所示,例如 start_date
= '2022-01-25' 和 end_date
= '2022-02-04'.
start_date | end_date |
---|---|
2022-01-25 | 2022-02-04 |
2018-08-31 | 2018-10-05 |
我正在尝试从上面创建一个新的 table 并添加另一列 days_count
,这需要 start_date 1/25,看看有多少天那个月(第一行是 7,因为 1/25、1/26、1/27、1/28、1/29、1/30、1/31),下一行是 4,因为 2/1 是 4 天- 2/4:
month | start_date | end_date | days_count |
---|---|---|---|
2022-01-01 | 2022-01-25 | 2022-02-04 | 7 |
2022-02-01 | 2022-01-25 | 2022-02-04 | 4 |
2018-08-01 | 2018-08-31 | 2018-10-05 | 1 |
2018-09-01 | 2018-08-31 | 2018-10-05 | 30 |
2018-10-01 | 2018-08-31 | 2018-10-05 | 5 |
您应该添加另一列来指示您正在计算的计数类型,但您可以使用 datediff
、last_day
和 date_trunc
(首先获取月)。这是一个例子
set start_date='2022-01-25'::date;
set end_date='2022-02-04'::date;
select $start_date,
$end_date,
'Start_Remainder' as label,
datediff(day,$start_date,last_day($start_date))+1 as days_count
union all
select $start_date,
$end_date,
'End_Accrued' as label,
datediff(day,date_trunc('month',$end_date),$end_date)+1 as days_count
如果我是你,我会在单独的列中显示计数
select $start_date,
$end_date,
datediff(day,$start_date,last_day($start_date))+1 as Start_Remainder_Days,
datediff(day,date_trunc('month',$end_date),$end_date)+1 as End_Accrued_Days
有一个 CTE 提供数据,还有几个 pre-conditioning CTE
WITH data_table(start_date, end_date) as (
SELECT * from values
('2022-01-25'::date, '2022-02-04'::date),
('2018-08-31'::date, '2018-10-05'::date)
), large_range as (
SELECT row_number() over (order by null)-1 as rn
FROM table(generator(ROWCOUNT => 1000))
), pre_condition as (
SELECT
start_date
,end_date
,datediff('month', start_date, end_date) as m
FROM data_table
)
SELECT
date_trunc('month', dateadd('month', r.rn, d.start_date)) as month
,d.start_date
,d.end_date
,datediff('day', greatest(d.start_date, month), least(d.end_date, dateadd('day', -1, dateadd('month', 1, month))))+1 as days_count
FROM pre_condition as d
JOIN large_range as r ON r.rn <= d.m
ORDER BY d.start_date, month;
给出:
MONTH | START_DATE | END_DATE | DAYS_COUNT |
---|---|---|---|
2018-08-01 | 2018-08-31 | 2018-10-05 | 1 |
2018-09-01 | 2018-08-31 | 2018-10-05 | 30 |
2018-10-01 | 2018-08-31 | 2018-10-05 | 5 |
2022-01-01 | 2022-01-25 | 2022-02-04 | 7 |
2022-02-01 | 2022-01-25 | 2022-02-04 | 4 |
如果您不喜欢 CTE 的外观
SELECT
date_trunc('month', dateadd('month', r.rn, d.start_date)) as month
,d.start_date
,d.end_date
,datediff('day', greatest(d.start_date, month), least(d.end_date, dateadd('day', -1, dateadd('month', 1, month))))+1 as days_count
FROM (
SELECT
start_date
,end_date
,datediff('month', start_date, end_date) as m
FROM data_table
) as d
JOIN (
SELECT row_number() over (order by null)-1 as rn
FROM table(generator(ROWCOUNT => 1000))
) as r ON r.rn <= d.m
ORDER BY d.start_date, month;