suponha que eu tenha a seguinte tabela
+-----------+-------------+
| DAY | LEAP YEAR |
+-----------+-------------+
| 7 | true |
| 167 | false |
| 43 | true |
| 60 | true |
| 256 | false |
| 340 | false |
+-----------+-------------+
usando apenas funções SQL, como alguém "converteria" esses dias do ano em combinações reais de dia/mês? o resultado seria 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 |
+-----------+-------------+------------+
Responder1
Uma propriedade interessante dos anos bissextos é que eles são todos iguais (exceto cerca de cem anos). Portanto, você pode escolher qualquer ano bissexto ou não bissexto e obter o mesmo resultado para todos os outros. Por exemplo, 2016 é um ano bissexto e 2015 não. Dadas essas informações, você pode usar o DDD
formador de data (dia deano) e use algumas case
expressões para obter as informações que você precisa:
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
Responder2
Maneira rápida e suja: escolha um ano que não seja bissexto e que seja bissexto. Coloque uma data = 1º de janeiro de cada ano em duas variáveis. Usando uma instrução CASE, some (valor do dia - 1) e qualquer variável de data apropriada. Em seguida, use uma instrução case ou mais SQL para obter o nome do mês e o dia dessa expressão.
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
Se você precisar lidar com nulos, deverá reescrever as expressões com o caso do lado de fora e adicionar uma ramificação para nulo.
Se você precisar que isso seja puramente uma instrução select, apenas codifique as datas na instrução case em vez de usar vars.