BlackBoard (http://www.black-board.net/index.php)
- Design, Programmierung & Entwicklung (http://www.black-board.net/board.php?boardid=55)
-- Programmieren (http://www.black-board.net/board.php?boardid=4)
--- PHP SQL Abfrage für Terminüberschneidungen (http://www.black-board.net/thread.php?threadid=23962)


Geschrieben von Se']['H am 17.02.2012 um 15:03:

Fragezeichen SQL Abfrage für Terminüberschneidungen

Hallo Leute,

ich habe ein Problem bezüglich einer Access Datenbank. Ich wollte eine Abfrage starten, indem die Datenbank nach Überschneidungen bei Terminen sucht.
Es geht darum das mehrere Mitarbeiter mehrere Einsätze an einem Tag haben die zu unterschiedlichen Zeiten anfangen, enden und wieder anfangen und enden.
Z.B:
1) "Arbeiter 1"; Start "17.02.2012 07:00:00"; Ende "17.02.2012 08:30:00"
2) "Arbeiter 2"; Start "17.02.2012 09:00:00"; Ende "17.02.2012 10:30:00"
3) "Arbeiter 1"; Start "17.02.2012 08:00:00"; Ende "17.02.2012 09:30:00"
4) "Arbeiter 2"; Start "17.02.2012 12:00:00"; Ende "17.02.2012 13:30:00"

Jetzt würde ich gerne eine Abfrage starten, die mir die Start- und Endzeiten abfragt und vergleicht ob sich da was überschneidet bezüglich des gleichen Arbeiters gibt und sie dann auswirft:
"Arbeiter 1"; Start "17.02.2012 07:00:00"; Ende "17.02.2012 08:30:00"
"Arbeiter 1"; Start "17.02.2012 08:00:00"; Ende "17.02.2012 09:30:00"

Die Tabelle für Startdatum/zeit und Endedatum/zeit ist in diesem Format aufgebaut: "tt.mm.jjjj hh.mm.ss"
dies kann nicht verändert werden.

Ich habe schon einen Ansatz gemacht wo er die Daten und Uhrzeiten abgleicht und mir ausgibt. Das Einzige woran ist jetzt scheitere ist dass die Abfrage mir die Arbeiter vergleicht, also dass sie guckt ob es bei Arbeiter 1 diese Überschneidung existiert und mir diese ausgibt. Also sortiert nach den Arbeitern mit der Überschneidung.

Also:
"Arbeiter 1"; Start "17.02.2012 07:00:00"; Ende "17.02.2012 08:30:00"
"Arbeiter 1"; Start "17.02.2012 08:00:00"; Ende "17.02.2012 09:30:00"

und nicht:

"Arbeiter 1"; Start "17.02.2012 07:00:00"; Ende "17.02.2012 08:30:00"
"Arbeiter 2"; Start "17.02.2012 08:00:00"; Ende "17.02.2012 09:30:00"




Mein Ansatz ist :

SELECT Tabelle.tName, Tabelle.dtStart, Tabelle.dtEnde
FROM Tabelle, Tabelle AS T
WHERE (((Tabelle.tName)<>[T].[tName]) AND
((Tabelle.dtStart)<[T].[dtEnde]) AND
((Format(IIf([T.dtStart]<[Tabelle].[dtEnde],[Tabelle].[dtEnde]-[T].[dtStart
],""),"hh:nn:ss"))<>""))
ORDER BY T.tName;



ich sitze seit mehreren Stunden dran und verzweifle dran. Habe in mehreren Foren verschiedene Ansätze gelesen und ausprobiert, aber bis jetzt noch keinen Erfolg gehabt.

Ich hoffe dass mir hier jemand helfen kann. Wäre Ihm sehr sehr dankbar !!!



Geschrieben von LX am 27.02.2012 um 23:58:

 

Keine Ahnung, wie das explizit bei Access laufen würde bzw. wie du das Datum in einen Timestamp oder ein vergleichbares Konstrukt gecastet bekommst, aber normalerweise würde das in etwa so aussehen. Du JOINst die Tabelle auf sich selbst und gibst dann die Datensätze aus, deren Datum sich wie folgt verhält:

code:
1:
2:
3:
4:
5:
6:
SELECT t2.*
  FROM tabelle t1
LEFT JOIN tabelle t2
   ON t2.dtStart < t1.dtEnde
  AND t2.dtEnde  > t1.dtStart
  AND t2.tName   = t1.tName


Voraussetzung ist wie gesagt, dass du die Datumsfelder in einen Datentyp umgewandelt bekommst, der sich mit Vergleichsabfragen behandeln lässt.



Geschrieben von Misel am 28.02.2012 um 10:32:

 

Die Darstellung der Zeit ist doch nur das, eine Darstellung. Wie das gespeichert wird, ist doch unabhängig davon. Deshalb nimm einfach den Date/Time-Datentyp und rechne so, wie LX es geschrieben hat. Erst, wenn der Nutzer es sehen soll, wird es dann in des gewünschte Format gebracht.



Geschrieben von Se']['H am 04.03.2012 um 18:32:

 

Ich habe vor kurzem erfahren, dass solch eine Abfrage in SQL garnicht geht. Also direkt nur in SQL. Mir wurde empfohlen Java zu benutzen und darüber diesen Abgleich zu machen.
Die Namen aller Arbeiter (keine Mehrfachnamen) mit einer Schleife auslesen und speichern, und dann mit einer weiteren Schleife die Liste aller Zeiten zu den bestehenden Arbeitern auslesen. Und dann eine weitere Schleife für die Überprüfung der Endzeit und der Anfangszeit.

Jedoch habe ich schon lange kein Java mehr programmiert und die Schleifen fallen mir etwas schwer. Wäre für eine kleine Starthilfe sehr dankbar.

Damit die Name ausgelesen und gespeichert werden bräuchte ich doch ne for-schleife die die Namen in ein Array speichert, oder ?
Und die schleife müsste doch kleiner sein als die Länge der Anzahl der Zeilen?
Also for (int i=o; i<column.length; i++) oder ?
Wie könnte ich jetzt so eine verschachtelte Schleife erstellen damit ich zuerst die Namen und dannnach die Daten/Uhrzeiten einlese damit ich sie für den Späteren Vergleich aufrufen kann?



Geschrieben von phoenix am 06.03.2012 um 15:05:

 

Also LXs Ansatz geht definitiv. Es liefert dir eine Ergebnismenge mit den Datensätzen, welche Überschneidungen bei der Start/Endzeit haben. Ein Problem mit dem casten sollte es bei MS Access nicht geben, da ich ohne jemals ernsthaft mit Access gearbeitet zu haben davon ausgehe, dass es automatisch den Datentyp erkennt und den Vergleich durchführt.

Zu deinem Java-Ansatz (ohne zu viel zu schreiben, da deine Angaben doch sehr spärlich sind):

Wieso möchtest du mehrfach auf eine Tabelle zugreifen um Daten zu holen, wenn diese auch alle mit einem Zugriff abrufbar sind?

Entweder du erstellst dir eine Liste mit Objekten (Objektattribute z. B. Mitarbeitername, Start- und Endezeit) oder schreibst alles was von der Datenbank kommt in ein Array. Nach deinem Zugriff bekommst du vom jdbc Treiber sehr wahrscheinlich ein Resultset zurück, welches du mit einem Iterator (Zauberwort: hasnext) überlaufen kannst und dir deine Objekte, Array, was auch immer du möchtest befüllen kannst. Dann schreibst du dir eine Methode, welche, über die Liste/Array geht und den Datums-/Zeitvergleich macht und die, die aus der Reihe tanzen irgendwo hinschreibst/ausgibst.

Bei einer for-Schleife über ein Objekt (Array, Liste,) solltest du immer auf die Anzahl der Säze gehen, die in deinem Objekt enthalten sind. Die Objekttypen besitzen eine .size()-Methode, die du verwenden kannst.

code:
1:
2:
for (int i = 0; i < meinetolleliste.size(); i++){..}
for (int i = 0; i < meintollesarray.size(); i++){..}


Vom Aufwand her ist die SQl-Lösung eindeutig schneller zu realisieren und einfacher.


Forensoftware: Burning Board 2.3.6, entwickelt von WoltLab GmbH