Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Finde überlappende (Datum/Uhrzeit) Zeilen innerhalb einer Tabelle

SELECT  m1.meetingID, m1.meetingStart, m1.meetingEnd, m2.meetingID
FROM    t_meeting m1, t_meeting m2
WHERE   (m2.meetingStart BETWEEN m1.meetingStart AND m1.meetingEnd
        OR m2.meetingEnd BETWEEN m1.meetingStart AND m1.meetingEnd)
        AND m1.meetingID <> m2.meetingID

Dadurch wird jedes Paar zweimal ausgewählt.

Wenn Sie möchten, dass jedes Paar nur einmal ausgewählt wird, verwenden Sie:

SELECT  m1.meetingID, m1.meetingStart, m1.meetingEnd, m2.meetingID
FROM    t_meeting m1, t_meeting m2
WHERE   (m2.meetingStart BETWEEN m1.meetingStart AND m1.meetingEnd
        OR m2.meetingEnd BETWEEN m1.meetingStart AND m1.meetingEnd)
        AND m2.meetingID > m1.meetingID

Stellen Sie sicher, dass Sie Indizes auf meetingStart haben und meetingEnd damit die Abfrage effizient funktioniert.

MySQL , wird jedoch wahrscheinlich INDEX MERGE verwenden um diese Abfrage auszuführen, die in der aktuellen Implementierung nicht sehr effizient ist.

Sie können auch versuchen, Folgendes zu verwenden:

SELECT  m1.*, m2.*
FROM    (
        SELECT  m1.meetingID AS mid1, m2.meetingID AS mid2
        FROM    t_meeting m1, t_meeting m2
        WHERE   m2.meetingStart BETWEEN m1.meetingStart AND m1.meetingEnd
                AND m2.meetingID <> m1.meetingID
        UNION
        SELECT  m1.meetingID, m2.meetingID
        FROM    t_meeting m1, t_meeting m2
        WHERE   m2.meetingEnd BETWEEN m1.meetingStart AND m1.meetingEnd
                AND m2.meetingID <> m1.meetingID
        ) mo, t_meeting m1, t_meeting m2
WHERE   m1.meetingID = mid1
        AND m2.meetingID = mid2

, die komplexer ist, aber höchstwahrscheinlich etwas schneller ausgeführt wird.