次のような表があるとします
+-----------+-------------+
| 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
閏年の素晴らしい点は、すべて同じであることです(100年を除く)。したがって、閏年または閏年でない年を選択するだけで、他のすべての年について同じ結果を得ることができます。たとえば、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 日の日付を 2 つの変数に入れます。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
null を処理する必要がある場合は、case を外側にして式を書き直し、null のブランチを追加する必要があります。
これを純粋に選択ステートメントにする必要がある場合は、変数を使用するのではなく、case ステートメントで日付をハードコードするだけです。