SQL - 年日を日/月に変換する

SQL - 年日を日/月に変換する

次のような表があるとします

+-----------+-------------+
|    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 ステートメントで日付をハードコードするだけです。

関連情報