| Yaslaw.Info > MySQL > [MySQL] Perioden vergleichen |
Impressum ∞ |
[MySQL] Perioden vergleichen
| Wichtiger Hinweis zu meinen MySQL-Statements |
|---|
| In meinen MySQL-Statements schreibe ich Kommentare die von -- oder von # eingeleitet werden. Einige MySQL-Editoren akzeptieren diese Kommentare nicht. Allen Voran phpMyAdmin. Um diese Scripte mit einem der betroffenen Tools zu testen, muss also jede Zeile die mit -- oder mit # beginnt gelöscht werden |
Wenn man 2 Perioden vergleichen will, wird es relativ komplex. Darum hier mal einige Ansätze
Datengrundlage der Beispiele
Die folgenden 2 Tabellen verwende ich in alle meinen Beispielen| id_1 | start_1 | end_1 |
|---|---|---|
| 1 | 2012-02-01 | 2012-02-28 |
| 2 | 2012-02-15 | 2012-03-15 |
| 3 | 2012-04-01 | 2012-04-15 |
| id_2 | start_2 | end_2 |
|---|---|---|
| 1 | 2012-03-20 | 2012-04-02 |
| 2 | 2012-02-15 | 2012-02-15 |
| 3 | 2012-01-01 | 2012-02-02 |
| 4 | 2012-01-01 | 2012-12-31 |
Nur Überschneidende Perioden ausgeben
Als erstes Beispiel interessiert uns, welche Perioden_2 sich mit welchen Perioden_1 überschneiden. Also eine einfache AusfilterungSELECT
p1.id_1,
p1.start_1,
p1.end_1,
p2.id_2,
p2.start_2,
p2.end_2
FROM
tbl_periode_1 AS p1,
tbl_periode_2 AS p2
WHERE
LEAST(end_2, end_1) >= GREATEST(start_2, start_1)
ORDER BY
id_1,
id_2;
p1.id_1,
p1.start_1,
p1.end_1,
p2.id_2,
p2.start_2,
p2.end_2
FROM
tbl_periode_1 AS p1,
tbl_periode_2 AS p2
WHERE
LEAST(end_2, end_1) >= GREATEST(start_2, start_1)
ORDER BY
id_1,
id_2;
Das Resultat sieht dann so aus
|
Periode 1
|
Periode 2
| ||||
| id_1 | start_1 | end_1 | id_2 | start_2 | end_2 |
|---|---|---|---|---|---|
| 1 | 2012-02-01 | 2012-02-28 | 2 | 2012-02-15 | 2012-02-15 |
| 1 | 2012-02-01 | 2012-02-28 | 3 | 2012-01-01 | 2012-02-02 |
| 1 | 2012-02-01 | 2012-02-28 | 4 | 2012-01-01 | 2012-12-31 |
| 2 | 2012-02-15 | 2012-03-15 | 2 | 2012-02-15 | 2012-02-15 |
| 2 | 2012-02-15 | 2012-03-15 | 4 | 2012-01-01 | 2012-12-31 |
| 3 | 2012-04-01 | 2012-04-15 | 1 | 2012-03-20 | 2012-04-02 |
| 3 | 2012-04-01 | 2012-04-15 | 4 | 2012-01-01 | 2012-12-31 |
Schnittperioden ermitteln
Wenn sich 2 Perioden überschneiden, dann interessiert mich jetzt die sich überschneidende Periode. Also von wann und bis wann die Periode 1 und die Periode 2 sich überschneiden.Das SQL ist eigentlich dasselbe wie zuvor. Ich ergänze es nur noch um die Berechnung der Anzahl Tage sowie das Start und End-Datum
SELECT
-- Beide Perioden auslesen
p1.id_1,
p1.start_1,
p1.end_1,
p2.id_2,
p2.start_2,
p2.end_2,
-- Die länge der Schnittperiode ermitteln
DATEDIFF(LEAST(end_2, end_1), GREATEST(start_2, start_1))+1 AS days,
-- Start und Endzeit von der Resultat-Periode berechnen
GREATEST(start_2, start_1) AS start_date,
LEAST(end_2, end_1) AS end_date
FROM
tbl_periode_1 AS p1,
tbl_periode_2 AS p2
WHERE
LEAST(end_2, end_1) >= GREATEST(start_2, start_1)
ORDER BY
id_1,
id_2;
-- Beide Perioden auslesen
p1.id_1,
p1.start_1,
p1.end_1,
p2.id_2,
p2.start_2,
p2.end_2,
-- Die länge der Schnittperiode ermitteln
DATEDIFF(LEAST(end_2, end_1), GREATEST(start_2, start_1))+1 AS days,
-- Start und Endzeit von der Resultat-Periode berechnen
GREATEST(start_2, start_1) AS start_date,
LEAST(end_2, end_1) AS end_date
FROM
tbl_periode_1 AS p1,
tbl_periode_2 AS p2
WHERE
LEAST(end_2, end_1) >= GREATEST(start_2, start_1)
ORDER BY
id_1,
id_2;
|
Periode 1
|
Periode 2
|
Schnittperiode
| ||||||
| id_1 | start_1 | end_1 | id_2 | start_2 | end_2 | days | start_date | end_date |
|---|---|---|---|---|---|---|---|---|
| 1 | 2012-02-01 | 2012-02-28 | 2 | 2012-02-15 | 2012-02-15 | 1 | 2012-02-15 | 2012-02-15 |
| 1 | 2012-02-01 | 2012-02-28 | 3 | 2012-01-01 | 2012-02-02 | 2 | 2012-02-01 | 2012-02-02 |
| 1 | 2012-02-01 | 2012-02-28 | 4 | 2012-01-01 | 2012-12-31 | 28 | 2012-02-01 | 2012-02-28 |
| 2 | 2012-02-15 | 2012-03-15 | 2 | 2012-02-15 | 2012-02-15 | 1 | 2012-02-15 | 2012-02-15 |
| 2 | 2012-02-15 | 2012-03-15 | 4 | 2012-01-01 | 2012-12-31 | 30 | 2012-02-15 | 2012-03-15 |
| 3 | 2012-04-01 | 2012-04-15 | 1 | 2012-03-20 | 2012-04-02 | 2 | 2012-04-01 | 2012-04-02 |
| 3 | 2012-04-01 | 2012-04-15 | 4 | 2012-01-01 | 2012-12-31 | 15 | 2012-04-01 | 2012-04-15 |
Meine ersten Versuche - sehr kompliziert, aber zu schade zum vernichten...
Alte Version
Code um die Testdaten zu erstellen
DROP TABLE tbl_periode_1;
CREATE TABLE tbl_periode_1
SELECT 1 AS id_1, DATE('2012-02-01') AS start_1, DATE('2012-02-28') AS end_1
UNION ALL SELECT 2, DATE('2012-02-15'), DATE('2012-03-15')
UNION ALL SELECT 3, DATE('2012-04-01'), DATE('2012-04-15');
DROP TABLE tbl_periode_2;
CREATE TABLE tbl_periode_2
SELECT 1 AS id_2, DATE('2012-03-20') AS start_2, DATE('2012-04-02') AS end_2
UNION ALL SELECT 2, DATE('2012-02-15'), DATE('2012-02-15')
UNION ALL SELECT 3, DATE('2012-01-01'), DATE('2012-02-02')
UNION ALL SELECT 4, DATE('2012-01-01'), DATE('2012-12-31');
CREATE TABLE tbl_periode_1
SELECT 1 AS id_1, DATE('2012-02-01') AS start_1, DATE('2012-02-28') AS end_1
UNION ALL SELECT 2, DATE('2012-02-15'), DATE('2012-03-15')
UNION ALL SELECT 3, DATE('2012-04-01'), DATE('2012-04-15');
DROP TABLE tbl_periode_2;
CREATE TABLE tbl_periode_2
SELECT 1 AS id_2, DATE('2012-03-20') AS start_2, DATE('2012-04-02') AS end_2
UNION ALL SELECT 2, DATE('2012-02-15'), DATE('2012-02-15')
UNION ALL SELECT 3, DATE('2012-01-01'), DATE('2012-02-02')
UNION ALL SELECT 4, DATE('2012-01-01'), DATE('2012-12-31');
| Yaslaw.Info, Die Homepage∞ | Mein Programmierer Wiki∞ | Mein Planungs Wiki∞ |
