Ich habe zwei Parameter zu finden:Wie nächsten X-ten des Monats nach einem Datum
- ein Datum (Bsp: 22/11/2016)
- eine Tagesnummer (zB: 25)
ich möchte die nächsten 25 Monate nach 22/11/2016 finden: 25/11/2016
Ich habe zwei Parameter zu finden:Wie nächsten X-ten des Monats nach einem Datum
ich möchte die nächsten 25 Monate nach 22/11/2016 finden: 25/11/2016
select trunc(date '2016-11-22', 'month') + 25
from dual;
trunc(date '2016-11-22', 'month')
den ersten Tag des Monats, t Rückkehr er + 25
wird dann die gewünschten 25 Tage hinzufügen.
Wenn die Bedeutung des zweiten Parameters auf dem „Vergleich“ Datum hängt kann man so etwas tun:
select case
when extract(day from date '2016-11-22') >= 25 then
add_months(trunc(date '2016-11-22', 'month'), 1) + 25
else trunc(date '2016-11-22', 'month') + 25
end as next_date
from dual;
Natürlich würden ersetzen Sie fest einprogrammierte Werte für das Datum und die „Anzahl“ der Tage mit Variablen oder Spaltenwerten. Dieses Beispiel
:
with sample_data (the_date, num_days) as (
select date '2016-11-22', 25 from dual union all
select date ' 2016-11-26', 22 from dual union all
select date ' 2016-11-26', 3 from dual
)
select the_date, num_days,
case
when extract(day from the_date) >= num_days then
add_months(trunc(the_date, 'month'), 1) + num_days - 1
else trunc(the_date, 'month') + num_days - 1
end as next_date
from sample_data;
zurückkehren wird:
THE_DATE | NUM_DAYS | NEXT_DATE
------------+----------+------------
2016-11-22 | 25 | 2016-11-25
2016-11-26 | 22 | 2016-12-22
2016-11-26 | 3 | 2016-12-03
Sie können
LAST_DAY(<<a date>>) + <<a day number>> + 1
LAST_DAY gibt Ihnen den letzten Tag des Gebens, Monate (ei 30. November) Fügen Sie dann 1 Tag hinzu, um den 1. Dezember plus Ihre Tagesnummer zu erhalten.
Das würde am 25. Dezember für die Beispieldaten in der Frage ergeben. –
Ja, aber wie schon bemerkt ist die Frage nicht wirklich klar. –
könnten Sie verwenden diese
WITH tmp AS
(
SELECT TO_DATE('22/11/2016', 'DD/MM/YYYY') date_col FROM DUAL
)
SELECT
CASE WHEN TO_CHAR(date_col,'DD') > '25'
THEN TO_DATE('25' || TO_CHAR(ADD_MONTHS(date_col, 1), '/MM/yyyy'), 'DD/MM/YYYY')
ELSE TO_DATE('25' || TO_CHAR(date_col, '/MM/yyyy'), 'DD/MM/YYYY') END date_col_new
FROM tmp;
Wenn Sie Ihre Eingabe (25) Zahl ist, Sie TO_CHAR(your_input)
statt '25'
verwenden könnte es Ihr Problem lösen können:
select
(
case
when trunc (:yourdate-trunc(:yourdate,'month'))+1 <:urNum then
trunc(:yourdate,'month')+:urNum-1
else
trunc(last_day(:yourdate))+:urNum
end)
from dual;
hier ein weg:
WITH dates AS (SELECT to_date('30/11/2015', 'dd/mm/yyyy') dt FROM dual UNION ALL
SELECT to_date('03/11/2015', 'dd/mm/yyyy') dt FROM dual UNION ALL
SELECT to_date('31/10/2015', 'dd/mm/yyyy') dt FROM dual UNION ALL
SELECT to_date('29/11/2015', 'dd/mm/yyyy') dt FROM dual UNION ALL
SELECT to_date('31/01/2016', 'dd/mm/yyyy') dt FROM dual),
dom AS (SELECT 25 day_of_month FROM dual UNION ALL
SELECT 31 day_of_month FROM dual UNION ALL
SELECT 30 day_of_month FROM dual UNION ALL
SELECT 03 day_of_month FROM dual UNION ALL
SELECT 01 day_of_month FROM dual),
res AS (SELECT dates.dt starting_dt,
dom.day_of_month,
add_months(TRUNC(dates.dt, 'mm'),
CASE WHEN to_char(dates.dt, 'dd') >= dom.day_of_month
THEN 1
ELSE 0
END) month_of_end_dt
FROM dates
CROSS JOIN dom)
SELECT starting_dt,
day_of_month,
month_of_end_dt + least(day_of_month, to_number(to_char(last_day(month_of_end_dt), 'dd'))) - 1 next_date
FROM res
ORDER BY starting_dt, day_of_month;
STARTING_DATE DAY_OF_MONTH NEXT_DATE
------------- ------------ ----------
31/10/2015 1 01/11/2015
31/10/2015 3 03/11/2015
31/10/2015 25 25/11/2015
31/10/2015 30 30/11/2015
31/10/2015 31 30/11/2015
03/11/2015 1 01/12/2015
03/11/2015 3 03/12/2015
03/11/2015 25 25/11/2015
03/11/2015 30 30/11/2015
03/11/2015 31 30/11/2015
29/11/2015 1 01/12/2015
29/11/2015 3 03/12/2015
29/11/2015 25 25/12/2015
29/11/2015 30 30/11/2015
29/11/2015 31 30/11/2015
30/11/2015 1 01/12/2015
30/11/2015 3 03/12/2015
30/11/2015 25 25/12/2015
30/11/2015 30 30/12/2015
30/11/2015 31 30/11/2015
31/01/2016 1 01/02/2016
31/01/2016 3 03/02/2016
31/01/2016 25 25/02/2016
31/01/2016 30 29/02/2016
31/01/2016 31 29/02/2016
Was dies tut ist, dass es zuerst den Monat findet, in dem das neue Datum sein wird, indem es den Tag mit dem Datum vergleicht, mit dem verglichen wird. (dh wenn der Tag des Datums, an dem Sie ankommen möchten, bereits hinter dem Tag des Startdatums liegt, fügen Sie einen Monat hinzu, andernfalls fügen Sie nichts hinzu).
Sobald Sie das haben, ist es eine einfache Sache, die Anzahl der Tage hinzuzufügen, die Sie versuchen zu erreichen.
Ich habe angenommen, dass, wenn der Monat nicht die volle Anzahl von Tagen hat (zB Februar, April, Juni, September, November), Sie wollen, was auch immer der letzte Tag des Monats ist.
Daher wählen wir, was immer niedriger ist - den letzten Tag des Monats oder den Tag, den Sie erreichen möchten. Wir müssen eins von diesem Ergebnis subtrahieren, da wir den ersten des Monats in die Zählung einbeziehen wollen.
Aber was, wenn mein Datum ist 22/11/2016 und ich möchte das nächste 3. des Monats (03/12/2016)? – Zedfax
Keine richtige Antwort. Wenn die Eingabe 2016-11-26 ist, sollte die Ausgabe 2016-12-25 sein. Zedfax - Bitte überprüfen. – Ubercool
Scheint wie Ihr Datum '22/11/2016' ist behoben und Sie wollen alle Daten nach diesem Fall gibt es keine generische Lösung. Sie müssen Ihre Abfrage drehen und drehen, um Ihre gewünschten Daten zu erreichen. – XING