假设我有下表
+-----------+-------------+
| DAY | LEAP YEAR |
+-----------+-------------+
| 7 | true |
| 167 | false |
| 43 | true |
| 60 | true |
| 256 | false |
| 340 | false |
+-----------+-------------+
仅使用 SQL 函数,如何将这些年日“转换”为实际的日/月组合?结果将类似于:
+-----------+-------------+------------+
| DAY | LEAP YEAR | RESULT |
+-----------+-------------+------------+
| 7 | true | 7 Jan |
| 167 | false | 16 Jun |
| 43 | true | 12 Feb |
| 60 | true | 29 Feb |
| 256 | false | 13 Sep |
| 340 | false | 6 Dec |
+-----------+-------------+------------+
答案1
闰年的一个巧妙特性是它们都是相同的(除了整数百年)。因此,您可以选择任何闰年或非闰年,并为所有其他年份获得相同的结果。例如,2016 年是闰年,而 2015 年不是。有了这些信息,您可以使用DDD
日期格式化程序(日期年),并使用一些case
表达式来获取所需的信息:
SELECT TO_CHAR(
TO_DATE(TO_CHAR(day) ||
'-' ||
CASE leap_year
WHEN 'true' THEN '2016'
ELSE '2015'
END,
'DDD-YYYY'),
'dd month') AS result
FROM my_table
答案2
快速而粗略的方法:选择一个非闰年和一个闰年。将日期 = 每年 1 月 1 日放入两个变量中。使用 CASE 语句,将 (日期值 - 1) 和任何适当的日期变量相加。然后使用 case 语句或更多 SQL 从此表达式中获取月份名称和日期。
declare @normal_year_nyd date = '1-1-2015';
declare @leap_year_nyd date = '1-1-2016';
select
t.[day], -- highly suggest naming this something other than 'day' to avoid ambiguous code
t.leap_year,
datename(month, dateadd(day, t.[day] - 1,
case
when t.leap_year = 'false'
then @normal_year_nyd
when t.leap_year = 'true'
then @leap_year_nyd
end)
) as month_name,
-- do the same as above replacing "month" with "day" in the dateadd expression
from my_table t
where t.leap_year is not null and t.[day] is not null
如果需要处理空值,则必须重写外部大小写的表达式并为空值添加分支。
如果您需要将其作为纯粹的选择语句,则只需在 case 语句中对日期进行硬编码,而不是使用变量。