Estou tentando escrever uma expressão de caso onde ela olha para a data de vencimento e, se já passou, escolhe a data de vencimento próxima ou mais próxima. Agora, devido a certa restrição de banco de dados, tenho que fazer isso manualmente. O problema é que meu código está comparando o dia extraído (a) do due_date com o dia extraído (b) do time_stamp atual e se a < b significa que a data de vencimento do mês atual passou e o próximo seria ( a / mês atual + 1) <- Exemplo de formato de data a / Out.
Agora o problema é se o mês atual for 12 (dez) isso faria o próximo vencimento a/13 que eu não quero. Alguma maneira de limitar a 12 e redefinir para 1?
Além disso, pontos de bônus se você puder me ajudar na parte do ano?
due_date |current_timestamp | Result
----------- ----------------- -----------
2021-12-05 |2022-10-18 | 2022-11-05
2022-06-02 |2022-10-18 | 2022-11-02
2022-10-19 |2022-10-18 | 2022-10-19
2022-10-15 |2022-10-18 | 2022-11-15
2021-10-20 |2022-10-18 | 2022-10-20
CASE
WHEN EXTRACT(DAY FROM due_date ) < EXTRACT(DAY FROM CURRENT_TIMESTAMP) THEN CONCAT(EXTRACT(DAY FROM due_date ),'/',(EXTRACT(Month FROM CURRENT_TIMESTAMP))+1)
ELSE CONCAT(EXTRACT(DAY FROM due_date ),'/',(EXTRACT(Month FROM CURRENT_TIMESTAMP)))
END AS "Next Payment Date"
Como regra geral, é melhor usar as funções de calendário tanto quanto possível em vez de calcular as partes ano-mês-dia separadamente.
Você não mencionou se o dia de uma data de vencimento pode ser 31/30/29, e então qual deve ser o resultado quando o mês atual não tiver esse dia. Alguns sistemas de cobrança resolvem esse problema nunca usando essas datas (normalmente, eles estão empurrando a data para o dia 1º do próximo mês). Vamos supor que seja o seu caso.
As duas datas que você precisa calcular são:
Com estes, basta selecionar uma das datas, dependendo do caso:
Resultado:
É útil lembrar que a maioria dos bancos de dados possui ferramentas que lidam com adição/subtração/comparação de data. Para Postgres, você pode encontrá-los aqui: https://www.postgresql.org/docs/current/functions-datetime.html
Eu não acho que o limite do ano é o que vai te dar dor de cabeça - os meses podem ter diferentes números de dias e não podemos simplesmente incrementar o valor do mês em 1 e ainda receber uma data válida. Para contornar essa limitação, usamos
INTERVAL
no Postgres (e algumas outras variantes do SQL também):Isso deve te dar o que você quer pelo que eu pude entender. Se houver necessidade de alguma modificação, por favor me avise:
A última condição funciona porque os meses "curtos" (fevereiro, abril, junho, setembro, novembro) são sempre precedidos/seguidos por meses com 31 dias.
Veja Fiddle aqui: https://www.db-fiddle.com/f/4jyoMCicNSZpjMt4jFYoz5/6061