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 DDD
formateador de fecha (día deaño) y utiliza algunas case
expresiones 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.