OK, das war ein lustiges Problem. Zusammenfassend: Sie erhalten ein Datum (in dem Oracle immer die Uhrzeit angibt), von dem aus Sie die Messung starten, sowie eine anfängliche Dauer in Minuten. Sie müssen das Ablaufdatum (wie immer Datum und Uhrzeit) finden, das berechnet wird, indem Sie die Dauer in Minuten zum Datum des Beginns der Uhr hinzufügen, aber die Uhr sollte nur während der Geschäftszeiten laufen - 9 bis 17, nur Montag bis Freitag (nicht am Wochenende).
Ich nehme an, wenn die "verbleibenden Minuten" 0 ist, dann sollte das Ablaufdatum das gleiche sein wie das "Uhr-Start" -Datum, wenn es innerhalb der Arbeitszeit fällt, oder 9 Uhr am nächsten Arbeitstag.
Um die Lösung zu verstehen, wollen wir sie in zwei Teile aufteilen. Betrachten wir zunächst einen ganz besonderen Fall: Die "Uhr beginnt" an einem Montag um 9 Uhr. Dann zerlegen Sie die verbleibenden Minuten in ein ganzzahliges Vielfaches von 2400 (5 * 8 * 60 = 2400 Minuten in einer vollen Arbeitswoche) plus ein ganzzahliges Vielfaches von 480 von dem, was übrig ist (480 Minuten zu einem Arbeitstag), plus was noch übrig ist. wenn überhaupt. Dann gilt: Das Ablaufdatum ist das "Uhr-Start" -Datum, plus viele Wochen, plus viele ganze Tage (zwischen 0 und 4) plus die restlichen Minuten. Ein Ausnahmefall hier: Wenn das "verbleibende Minuten" ein genaues Vielfaches von 480 Minuten ist, dann ist das Ablaufdatum um 17 Uhr an einem bestimmten Arbeitstag und nicht am nächsten Arbeitstag um 9 Uhr. Dies erfordert eine spezielle Handhabung in der Formel. All dies geschieht in der äußeren Abfrage (unten in der Lösung).
Dann müssen wir den allgemeinen Fall auf diesen speziellen Fall reduzieren. Dies geschieht in der Unterabfrage prep
in der Lösung. Ich verlängere einfach die "verbleibenden Minuten" um die Arbeitsminuten, die am Montag um 9 Uhr am Montag zu Beginn der Woche verstrichen sind. Dies ist eine relativ einfache Berechnung. Beachten Sie, dass, wenn das Datum des "Uhrbeginns" nach 17 Uhr an einem Freitag (oder zu irgendeiner Zeit am Samstag oder Sonntag) ist, ich genau 2400 Minuten hinzufügen muss, eine volle Arbeitswoche.
In der Lösung zeige ich eine Vielzahl von "Uhr Start" Daten, dt
, und noch Minuten, rm
. Ich habe eine Vielzahl von Situationen getestet, und ich denke, die Lösung ist korrekt, aber Sie möchten vielleicht mehr Daten testen (andere Situationen, die ich nicht in die Tests einbezogen habe).
with
inputs (task, min_rem, dt) as (
select 'Task1', 1800, to_date('27-10-16 9:45 AM', 'dd-mm-yy hh:mi AM') from dual union all
select 'Task2', 3400, to_date('28-10-16 9:45 AM', 'dd-mm-yy hh:mi AM') from dual union all
select 'Task3', 400, to_date('29-10-16 3:45 AM', 'dd-mm-yy hh:mi AM') from dual union all
select 'Task4', 180, to_date('30-10-16 9:45 AM', 'dd-mm-yy hh:mi AM') from dual union all
select 'Task5', 8400, to_date('31-10-16 9:45 PM', 'dd-mm-yy hh:mi AM') from dual union all
select 'Task6', 5000, to_date('01-11-16 5:00 PM', 'dd-mm-yy hh:mi AM') from dual union all
select 'Task7', 0, to_date('01-12-16 5:00 PM', 'dd-mm-yy hh:mi PM') from dual
),
prep (task, min_rem, dt, adj_min, adj_dt) as (
select task, min_rem, dt,
min_rem + case when dt > trunc(dt, 'iw') + 5 + 17/24 then 2400
else (trunc(dt) - trunc(dt, 'iw')) * 480 +
least(480, greatest(0, 1440 * (dt - trunc(dt) - 9/24)))
end,
trunc(dt, 'iw') + 9/24
from inputs
)
select task, min_rem, dt,
adj_dt + 7 * trunc(adj_min/2400)
+ case when adj_min/480 = trunc(adj_min/480)
then mod(adj_min, 2400)/480 - 1 + 8/24
else trunc(mod(adj_min, 2400)/480) + mod(adj_min, 480)/1440
end as expiration
from prep
order by task
;
Ausgang:
TASK MIN_REM DT EXPIRATION
----- ---------- ----------------- -----------------
Task1 1800 27-10-16 09:45 AM 01-11-16 03:45 PM
Task2 3400 28-10-16 09:45 AM 08-11-16 10:25 AM
Task3 400 29-10-16 03:45 AM 31-10-16 03:40 PM
Task4 180 30-10-16 09:45 AM 31-10-16 12:00 PM
Task5 8400 31-10-16 09:45 PM 24-11-16 01:00 PM
Task6 5000 01-11-16 05:00 PM 16-11-16 12:20 PM
Task7 0 01-12-16 05:00 PM 01-12-16 05:00 PM
7 rows selected
Bitte geben Sie einige Beispieleingabedaten und was Sie die Ergebnisse zu erwarten sein. – Boneist
Bitte aktualisieren Sie Ihre Frage mit den zusätzlichen Informationen. Denken Sie daran, dass wir Ihre Datenbank oder Ihre Anforderungen nicht sehen können. Daher müssen Sie so viele Informationen wie möglich zur Verfügung stellen, um Ihr Problem zu demonstrieren. – Boneist
Nein, Sie müssen Ihre Frage bearbeiten (wenn Sie sich Ihre Frage ansehen, sehen Sie unterhalb der Tags 'sql' und' oracle11g' 'share edit close flag' - klicken Sie auf' edit') und fügen Sie die zusätzlichen Informationen hinzu Dort. Auf diese Weise können Sie es besser formatieren. – Boneist