Hallo, Radio SQL ist wieder auf Sendung! Kneten Sie die Ganglien, verbreiten Sie Pseudopodien (oder umgekehrt?) Und stellen Sie sich auf unsere Gravitationswelle ein!
Beim letzten Mal wurde ich fast geächtet, weil ich das Olympiad SQL-Problem analysiert hatte (
https://habr.com/en/post/359064/ ), angeblich war es nicht nah genug am Leben. Als ob die Tags "abnorme Programmierung" und "Olympiade" nicht für sich selbst sprechen. Aber offensichtlich liest niemand die Tags! Trotzdem werde ich das Thema Parsing-Aufgaben in der wunderbaren Programmiersprache SQL fortsetzen. Weil die Pfoten jucken.
Heute stehen wir vor einer ausschließlich lebensbedrohlichen und sogar praktischen Aufgabe. Ich bin darauf gestoßen und habe versucht, die Leistung des SLA auf Anfrage von liebevollen Benutzern zu berechnen. Das anfängliche Problem besteht im Wesentlichen wie folgt: Es war notwendig, die Arbeitsdauer für jede Anwendung zu berechnen und mit dem zu vergleichen, was wir versprochen hatten. Alles wäre in Ordnung, aber die Zeit in den Verpflichtungen wurde für funktionierend erklärt, und aufgrund der Statusänderungen in den Anwendungen konnte ich nur einen Kalender erhalten. Und hier ist ein Gedanke! Hier ist sie, Aufgabe! Nicht zu kompliziert, aber auch nicht ganz trivial. Nur um die zentralen Teile Ihres autonomen Nervensystems zu dehnen und sie sympathischer zu machen!
Also gebe ich den Zustand an.
Es gibt mehrere Zeitintervalle, die durch das Datum und die Uhrzeit des Beginns und Endes angegeben werden (ein Beispiel in der PostgreSQL-Syntax):
with periods(id, start_time, stop_time) as ( values(1, '2019-03-29 07:00:00'::timestamp, '2019-04-08 14:00:00'::timestamp), (2, '2019-04-10 07:00:00'::timestamp, '2019-04-10 20:00:00'::timestamp), (3, '2019-04-11 12:00:00'::timestamp, '2019-04-12 16:07:12'::timestamp), (4, '2018-12-28 12:00:00'::timestamp, '2019-01-16 16:00:00'::timestamp) )
In einer SQL-Abfrage (c) muss die Dauer jedes Intervalls in Arbeitsstunden berechnet werden. Wir glauben, dass wir wochentags von Montag bis Freitag arbeiten, die Arbeitszeiten sind immer von 10:00 bis 19:00 Uhr. Darüber hinaus gibt es gemäß dem Produktionskalender der Russischen Föderation eine Reihe von offiziellen Feiertagen, die keine Arbeitstage sind, und einige der freien Tage sind im Gegenteil Arbeitstage, da dieselben Feiertage verschoben werden. Eine Verkürzung der Vorferientage ist nicht erforderlich, wir halten sie für vollständig. Da die Feiertage von Jahr zu Jahr variieren, dh durch explizite Auflistung festgelegt werden, beschränken wir uns auf Daten nur von 2018 und 2019. Ich bin sicher, dass die Lösung bei Bedarf leicht ergänzt werden kann.
Es ist erforderlich, eine Spalte mit der Dauer in Arbeitsstunden zu den Anfangsperioden von
Perioden hinzuzufügen. Hier ist das Ergebnis:
id | start_time | stop_time | work_hrs
Wir überprüfen die Anfangsdaten nicht auf Richtigkeit, sondern berücksichtigen immer
start_time <= stop_time .
Die speziellen SQL-Dialektkonstrukte von PostgreSQL können verwendet, aber nicht missbraucht werden. Zur vollständigen Richtigkeit der Bedingungen füge ich hinzu, dass die Abfrage unter PostgreSQL Version 10 oder höher ausgeführt werden muss.
In einem Monat wird es eine Analyse der Aufgabe geben. Ich bringe keine Entscheidungen, damit es einen Anreiz gibt, selbst zu entscheiden. Wir bitten Sie, den Code in den Kommentaren unter den Spoilern zu platzieren!
Zu guter Letzt . Wenn es mir bereits gelungen ist, diesen Artikel im Unternehmensblog von Postgres Professional zu veröffentlichen, werden wir einige Unternehmens-Goodies verwenden:
Um die interessanteste Lösung für dieses Problem zu finden, werden wir eine kostenlose Reise zu
PGConf.Russia 2020 spielen . Die Kriterien von Interesse sind persönlich meine und die der Kollegen, mit denen ich es für notwendig halte, sich zu beraten. Viel Glück
UPDATE! Ich sehe, dass Arbeitszeiten aus irgendeinem Grund ausschließlich ohne Arbeitsminuten wahrgenommen werden. Vergessen Sie nicht die Minuten! Ich habe die Anfangsintervalle und die erwartete Antwort angepasst, um die Verfügbarkeit von Minuten hervorzuheben.
UPDATE2- Zusammenfassung:
https://habr.com/en/company/postgrespro/blog/457722/ .