给定日期记录和间隔 30 天的第一个记录获取上一个计费周期
Get The Previous Billing Cycle Given The Date Record And First Record With A 30-day Interval
我正在尝试通过给定两个值来获取之前的结算周期:
- 首次记录日期
- 给定记录日期
鉴于上一个计费周期应在第一个记录日期的 30 天间隔内,我如何获得上一个计费周期?这里有一个 table 让您了解我在说什么:
|======================|======================|======================|
| first_record_date | date_recorded | prev_bill_cycle |
|======================|======================|======================|
| 2021-06-30 | 2021-11-15 | 2021-10-30 |
| 2021-06-15 | 2021-09-16 | 2021-09-15 |
| 2021-09-15 | 2021-09-16 | 2021-09-15 |
| 2021-06-30 | 2022-01-05 | 2021-12-30 |
| 2021-11-30 | 2022-11-31 | 2021-11-30 |
| 2020-02-29 | 2022-01-31 | 2022-01-29 |
| 2020-02-29 | 2022-01-31 | 2022-01-29 |
| 2020-02-29 | 2022-02-28 | 2022-02-28 |
| 2021-01-05 | 2022-01-03 | 2021-12-05 |
| 2021-01-05 | 2022-01-07 | 2022-01-05 |
|======================|======================|======================|
一些注意事项:
- 年份与
date_recorded
相同,除非记录月份为 1
- Dates/day 始终与第一个记录相同,除非在闰年或某些月份有 31 天
- 如果记录日小于第一个记录,除了闰年或某些月份有 31 天,则月份早于日期。
这是我目前得到的结果:
SELECT
first_record,
record_date,
(
CASE
WHEN date_recorded::DATE <= first_record::DATE THEN first_record_date
WHEN date_recorded::DATE - INTERVAL '30 day' <= first_recorded_date::DATE THEN first_recorded_date
WHEN date_recorded::DATE - INTERVAL '30 day' > CONCAT(TO_CHAR(date_recorded,'YYYY-MM-'),TO_CHAR(first_recorded_date,'DD'))::DATE
THEN CONCAT(TO_CHAR(date_recorded,'YYYY-MM-'),TO_CHAR(first_recorded_date,'DD'))::DATE
WHEN date_recorded::DATE - INTERVAL '30 day' > first_recorded_date::DATE THEN date_recorded
ELSE date_recorded::DATE
END
)AS previous_billing_cycle
FROM records_table
我遇到了闰年问题,或者日期与 first_record_date
日期不匹配。例如,有些月份没有第 31 天。
这是 DB-Fiddle 中的示例:https://www.db-fiddle.com/f/rZcgNiB9Nrt2PgVm2WnywA/5
我意识到使用 CASE/IF 语句是行不通的,因为自 first_record_date
.
以来的 30 个间隔天的计算不一定匹配
代码如下:
SELECT
first_record_date,
date_recorded,
DATE_PART('day', (first_record_date::DATE + INTERVAL '90 day') - first_record_date::DATE) AS first_and_next_cycle_date,
date_recorded::DATE - first_record_date::DATE AS date_recorded_minus_first_record,
(date_recorded::DATE - first_record_date::DATE)::INTEGER / 30 AS multiplier,
DATE_PART('day', (first_record_date::DATE + INTERVAL '30 day' * ((date_recorded::DATE - first_record_date::DATE)::INTEGER / 30)) - first_record_date::DATE) AS additional_days,
first_record_date::DATE + INTERVAL '1 day' * DATE_PART('day', (first_record_date::DATE + INTERVAL '30 day' * ((date_recorded::DATE - first_record_date::DATE)::INTEGER / 30)) - first_record_date::DATE) AS previous_billing_cycle,
first_record_date::DATE + INTERVAL '1 day' * DATE_PART('day', (first_record_date::DATE + INTERVAL '30 day' * (((date_recorded::DATE - first_record_date::DATE)::INTEGER / 30) + 1)) - first_record_date::DATE) AS end_billing_cycle
FROM records
数据库 fiddle 中的答案如下:
https://www.db-fiddle.com/f/rZcgNiB9Nrt2PgVm2WnywA/9
我正在尝试通过给定两个值来获取之前的结算周期:
- 首次记录日期
- 给定记录日期
鉴于上一个计费周期应在第一个记录日期的 30 天间隔内,我如何获得上一个计费周期?这里有一个 table 让您了解我在说什么:
|======================|======================|======================|
| first_record_date | date_recorded | prev_bill_cycle |
|======================|======================|======================|
| 2021-06-30 | 2021-11-15 | 2021-10-30 |
| 2021-06-15 | 2021-09-16 | 2021-09-15 |
| 2021-09-15 | 2021-09-16 | 2021-09-15 |
| 2021-06-30 | 2022-01-05 | 2021-12-30 |
| 2021-11-30 | 2022-11-31 | 2021-11-30 |
| 2020-02-29 | 2022-01-31 | 2022-01-29 |
| 2020-02-29 | 2022-01-31 | 2022-01-29 |
| 2020-02-29 | 2022-02-28 | 2022-02-28 |
| 2021-01-05 | 2022-01-03 | 2021-12-05 |
| 2021-01-05 | 2022-01-07 | 2022-01-05 |
|======================|======================|======================|
一些注意事项:
- 年份与
date_recorded
相同,除非记录月份为 1 - Dates/day 始终与第一个记录相同,除非在闰年或某些月份有 31 天
- 如果记录日小于第一个记录,除了闰年或某些月份有 31 天,则月份早于日期。
这是我目前得到的结果:
SELECT
first_record,
record_date,
(
CASE
WHEN date_recorded::DATE <= first_record::DATE THEN first_record_date
WHEN date_recorded::DATE - INTERVAL '30 day' <= first_recorded_date::DATE THEN first_recorded_date
WHEN date_recorded::DATE - INTERVAL '30 day' > CONCAT(TO_CHAR(date_recorded,'YYYY-MM-'),TO_CHAR(first_recorded_date,'DD'))::DATE
THEN CONCAT(TO_CHAR(date_recorded,'YYYY-MM-'),TO_CHAR(first_recorded_date,'DD'))::DATE
WHEN date_recorded::DATE - INTERVAL '30 day' > first_recorded_date::DATE THEN date_recorded
ELSE date_recorded::DATE
END
)AS previous_billing_cycle
FROM records_table
我遇到了闰年问题,或者日期与 first_record_date
日期不匹配。例如,有些月份没有第 31 天。
这是 DB-Fiddle 中的示例:https://www.db-fiddle.com/f/rZcgNiB9Nrt2PgVm2WnywA/5
我意识到使用 CASE/IF 语句是行不通的,因为自 first_record_date
.
代码如下:
SELECT
first_record_date,
date_recorded,
DATE_PART('day', (first_record_date::DATE + INTERVAL '90 day') - first_record_date::DATE) AS first_and_next_cycle_date,
date_recorded::DATE - first_record_date::DATE AS date_recorded_minus_first_record,
(date_recorded::DATE - first_record_date::DATE)::INTEGER / 30 AS multiplier,
DATE_PART('day', (first_record_date::DATE + INTERVAL '30 day' * ((date_recorded::DATE - first_record_date::DATE)::INTEGER / 30)) - first_record_date::DATE) AS additional_days,
first_record_date::DATE + INTERVAL '1 day' * DATE_PART('day', (first_record_date::DATE + INTERVAL '30 day' * ((date_recorded::DATE - first_record_date::DATE)::INTEGER / 30)) - first_record_date::DATE) AS previous_billing_cycle,
first_record_date::DATE + INTERVAL '1 day' * DATE_PART('day', (first_record_date::DATE + INTERVAL '30 day' * (((date_recorded::DATE - first_record_date::DATE)::INTEGER / 30) + 1)) - first_record_date::DATE) AS end_billing_cycle
FROM records
数据库 fiddle 中的答案如下: https://www.db-fiddle.com/f/rZcgNiB9Nrt2PgVm2WnywA/9