sql - conversión año día a día/mes

sql - conversión año día a día/mes

supongo que tengo la siguiente tabla

+-----------+-------------+
|    DAY    |  LEAP YEAR  |
+-----------+-------------+
|    7      |    true     |
|    167    |    false    |
|    43     |    true     |
|    60     |    true     |
|    256    |    false    |
|    340    |    false    |
+-----------+-------------+

Usando solo funciones SQL, ¿cómo se podrían "convertir" estos días del año en combinaciones reales de día/mes? el resultado sería algo como:

+-----------+-------------+------------+
|    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    |
+-----------+-------------+------------+

Respuesta1

Una propiedad interesante de los años bisiestos es que todos son iguales (excepto los cien años). Así que podrías elegir cualquier año bisiesto o no bisiesto y obtener el mismo resultado para todos los demás. Por ejemplo, 2016 es un año bisiesto y 2015 no. Dada esa información, puede utilizar el DDDformateador de fecha (día deaño) y utiliza algunas caseexpresiones para obtener la información que necesitas:

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

Respuesta2

Manera rápida y sucia: elija un año que no sea bisiesto y otro que sí lo sea. Coloque una fecha = 1 de enero de cada año en dos variables. Usando una declaración CASE, sume (valor del día - 1) y cualquier variable de fecha que sea apropiada. Luego use una declaración de caso o más SQL para obtener el nombre del mes y el día de esta expresión.

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

Si necesita manejar nulos, debe reescribir las expresiones con el caso en el exterior y agregar una rama para nulos.

Si necesita que esto sea puramente una declaración de selección, simplemente codifique las fechas en la declaración del caso en lugar de usar las vars.

información relacionada