案例陈述:当日期距当年超过 90 年时 THEN 最大日期距当前日期 90 年
Case statement: WHEN date is more than 90 years from current year THEN max date out at 90 years from current date
我有一个包含人们生日的日期列。其中一些包含 90 多年前的日期,我希望将这些日期限制在 90 年前。
例子
current desired
1930-01-01 1932-01-01
1930-02-11 1932-02-11
如您所见,如果生日自然超过 90 年,则期望的状态是让生日从当前日期算起 90 年。
它比我最初猜想的更棘手,它可以写得更简单,现在似乎有“竞争”,虽然,这比以前更不可读
90后无日期版本:
SELECT column1 as "current"
,iff(column1 < dateadd('year',-90, CURRENT_DATE),
date_from_parts(
year(CURRENT_DATE) - 90 + (month(column1)*100+day(column1) < month(CURRENT_DATE)*100 + day(CURRENT_DATE))::int,
month(column1),
day(column1)),
column1
) as desired
FROM VALUES
('1934-01-01'::date),
('1932-03-28'::date),
('1932-03-20'::date),
('1931-03-28'::date),
('1931-03-20'::date),
('1930-01-01'::date),
('1930-02-11'::date);
current
DESIRED
1934-01-01
1934-01-01
1932-03-28
1932-03-28
1932-03-20
1933-03-20
1931-03-28
1932-03-28
1931-03-20
1933-03-20
1930-01-01
1933-01-01
1930-02-11
1933-02-11
90 年前(又名标题)版本之前的年份:
SELECT column1 as "current"
,iff(year(column1) < year(CURRENT_DATE)-90, date_from_parts(year(CURRENT_DATE)-90, month(column1), day(column1)), column1) as desired
FROM VALUES
('1934-01-01'::date),
('1932-03-28'::date),
('1932-03-20'::date),
('1931-03-28'::date),
('1931-03-20'::date),
('1930-01-01'::date),
('1930-02-11'::date)
;
current
DESIRED
1934-01-01
1934-01-01
1932-03-28
1932-03-28
1932-03-20
1932-03-20
1931-03-28
1932-03-28
1931-03-20
1932-03-20
1930-01-01
1932-01-01
1930-02-11
1932-02-11
只唱CASE:
因此,由于在 CASE 语句的上下文中被要求,我又写了一遍(并修复了年份部分),但也将其解构,因此可以看出逻辑:
SELECT column1 as birth_day
,dateadd('year',-90, CURRENT_DATE) as ninety_years_ago
,year(ninety_years_ago) as ninety_years_ago_year
,(month(CURRENT_DATE)*100) + day(CURRENT_DATE) as current_partial_year
,(month(birth_day)*100) + day(birth_day) as birth_day_partial_year
,case when birth_day_partial_year < current_partial_year then 1 else 0 end as partial_year_correction
,(birth_day_partial_year < current_partial_year)::int as current_partial_year_alt_version /* not used just showing how it works */
,case
WHEN column1 < ninety_years_ago then
date_from_parts(ninety_years_ago_year + partial_year_correction, month(birth_day), day(birth_day))
ELSE
birth_day
END as desired
FROM VALUES
('1934-01-01'::date),
('1932-04-28'::date),
('1932-03-20'::date),
('1931-04-28'::date),
('1931-03-20'::date),
('1930-01-01'::date),
('1930-02-11'::date);
给出:
BIRTH_DAY
NINETY_YEARS_AGO
NINETY_YEARS_AGO_YEAR
CURRENT_PARTIAL_YEAR
BIRTH_DAY_PARTIAL_YEAR
PARTIAL_YEAR_CORRECTION
CURRENT_PARTIAL_YEAR_ALT_VERSION
DESIRED
1934-01-01
1932-03-31
1932
331
101
1
1
1934-01-01
1932-04-28
1932-03-31
1932
331
428
0
0
1932-04-28
1932-03-20
1932-03-31
1932
331
320
1
1
1933-03-20
1931-04-28
1932-03-31
1932
331
428
0
0
1932-04-28
1931-03-20
1932-03-31
1932
331
320
1
1
1933-03-20
1930-01-01
1932-03-31
1932
331
101
1
1
1933-01-01
1930-02-11
1932-03-31
1932
331
211
1
1
1933-02-11
这确实是一个棘手的问题。我什至在 timeanddate.com 检查了最长 90 年的日期差异 - 看起来不错。如果有人在这方面发现问题,请提供反馈。
select iff(extract(year,dateadd('year',90,column1::date))>extract(year,'2022-02-28'::date),
column1,
dateadd(day,
datediff(day,column1::date,dateadd(year,-90,'2022-02-28'::date)),
column1::date
)) as test
from
values
('1932-02-29'::date)
,('1932-02-28'::date)
,('1932-03-01'::date)
,('1928-02-29'::date)
,('1924-02-29'::date)
,('1930-01-01'::date)
,('1940-05-01'::date)
,('1950-12-01'::date)
,('1980-10-01'::date)
,('1920-06-01'::date)
;
+------------+
| TEST |
|------------|
| 1932-02-28 |
| 1932-02-28 |
| 1932-02-28 |
| 1932-02-28 |
| 1932-02-28 |
| 1932-02-28 |
| 1940-05-01 |
| 1950-12-01 |
| 1980-10-01 |
| 1932-02-28 |
+------------+
我有一个包含人们生日的日期列。其中一些包含 90 多年前的日期,我希望将这些日期限制在 90 年前。
例子
current desired
1930-01-01 1932-01-01
1930-02-11 1932-02-11
如您所见,如果生日自然超过 90 年,则期望的状态是让生日从当前日期算起 90 年。
它比我最初猜想的更棘手,它可以写得更简单,现在似乎有“竞争”,虽然,这比以前更不可读
90后无日期版本:
SELECT column1 as "current"
,iff(column1 < dateadd('year',-90, CURRENT_DATE),
date_from_parts(
year(CURRENT_DATE) - 90 + (month(column1)*100+day(column1) < month(CURRENT_DATE)*100 + day(CURRENT_DATE))::int,
month(column1),
day(column1)),
column1
) as desired
FROM VALUES
('1934-01-01'::date),
('1932-03-28'::date),
('1932-03-20'::date),
('1931-03-28'::date),
('1931-03-20'::date),
('1930-01-01'::date),
('1930-02-11'::date);
current | DESIRED |
---|---|
1934-01-01 | 1934-01-01 |
1932-03-28 | 1932-03-28 |
1932-03-20 | 1933-03-20 |
1931-03-28 | 1932-03-28 |
1931-03-20 | 1933-03-20 |
1930-01-01 | 1933-01-01 |
1930-02-11 | 1933-02-11 |
90 年前(又名标题)版本之前的年份:
SELECT column1 as "current"
,iff(year(column1) < year(CURRENT_DATE)-90, date_from_parts(year(CURRENT_DATE)-90, month(column1), day(column1)), column1) as desired
FROM VALUES
('1934-01-01'::date),
('1932-03-28'::date),
('1932-03-20'::date),
('1931-03-28'::date),
('1931-03-20'::date),
('1930-01-01'::date),
('1930-02-11'::date)
;
current | DESIRED |
---|---|
1934-01-01 | 1934-01-01 |
1932-03-28 | 1932-03-28 |
1932-03-20 | 1932-03-20 |
1931-03-28 | 1932-03-28 |
1931-03-20 | 1932-03-20 |
1930-01-01 | 1932-01-01 |
1930-02-11 | 1932-02-11 |
只唱CASE:
因此,由于在 CASE 语句的上下文中被要求,我又写了一遍(并修复了年份部分),但也将其解构,因此可以看出逻辑:
SELECT column1 as birth_day
,dateadd('year',-90, CURRENT_DATE) as ninety_years_ago
,year(ninety_years_ago) as ninety_years_ago_year
,(month(CURRENT_DATE)*100) + day(CURRENT_DATE) as current_partial_year
,(month(birth_day)*100) + day(birth_day) as birth_day_partial_year
,case when birth_day_partial_year < current_partial_year then 1 else 0 end as partial_year_correction
,(birth_day_partial_year < current_partial_year)::int as current_partial_year_alt_version /* not used just showing how it works */
,case
WHEN column1 < ninety_years_ago then
date_from_parts(ninety_years_ago_year + partial_year_correction, month(birth_day), day(birth_day))
ELSE
birth_day
END as desired
FROM VALUES
('1934-01-01'::date),
('1932-04-28'::date),
('1932-03-20'::date),
('1931-04-28'::date),
('1931-03-20'::date),
('1930-01-01'::date),
('1930-02-11'::date);
给出:
BIRTH_DAY | NINETY_YEARS_AGO | NINETY_YEARS_AGO_YEAR | CURRENT_PARTIAL_YEAR | BIRTH_DAY_PARTIAL_YEAR | PARTIAL_YEAR_CORRECTION | CURRENT_PARTIAL_YEAR_ALT_VERSION | DESIRED |
---|---|---|---|---|---|---|---|
1934-01-01 | 1932-03-31 | 1932 | 331 | 101 | 1 | 1 | 1934-01-01 |
1932-04-28 | 1932-03-31 | 1932 | 331 | 428 | 0 | 0 | 1932-04-28 |
1932-03-20 | 1932-03-31 | 1932 | 331 | 320 | 1 | 1 | 1933-03-20 |
1931-04-28 | 1932-03-31 | 1932 | 331 | 428 | 0 | 0 | 1932-04-28 |
1931-03-20 | 1932-03-31 | 1932 | 331 | 320 | 1 | 1 | 1933-03-20 |
1930-01-01 | 1932-03-31 | 1932 | 331 | 101 | 1 | 1 | 1933-01-01 |
1930-02-11 | 1932-03-31 | 1932 | 331 | 211 | 1 | 1 | 1933-02-11 |
这确实是一个棘手的问题。我什至在 timeanddate.com 检查了最长 90 年的日期差异 - 看起来不错。如果有人在这方面发现问题,请提供反馈。
select iff(extract(year,dateadd('year',90,column1::date))>extract(year,'2022-02-28'::date),
column1,
dateadd(day,
datediff(day,column1::date,dateadd(year,-90,'2022-02-28'::date)),
column1::date
)) as test
from
values
('1932-02-29'::date)
,('1932-02-28'::date)
,('1932-03-01'::date)
,('1928-02-29'::date)
,('1924-02-29'::date)
,('1930-01-01'::date)
,('1940-05-01'::date)
,('1950-12-01'::date)
,('1980-10-01'::date)
,('1920-06-01'::date)
;
+------------+
| TEST |
|------------|
| 1932-02-28 |
| 1932-02-28 |
| 1932-02-28 |
| 1932-02-28 |
| 1932-02-28 |
| 1932-02-28 |
| 1940-05-01 |
| 1950-12-01 |
| 1980-10-01 |
| 1932-02-28 |
+------------+