2010-05-19 5 views
1

J'ai une table MySQL avec les colonnes suivantes: id (int), la date (horodatage), starttime (varchar), endtime (varchar), ...comparaisons MySQL entre plusieurs lignes

Je dois trouver le temps emplacements qui sont occupés par deux lignes ou plus. Voici un exemple de tableau

id|  date   |starttime|endtime | 
__|_____________________|_________|________| 
1 | 2010-02-16 17:37:36 |14:35:00 |17:37:00| 
2 | 2010-02-17 12:24:22 |12:13:00 |14:32:00| 
3 | 2010-02-16 12:24:22 |15:00:00 |18:00:00| 

Les lignes 1 et 3 entrent en collision et doivent être corrigées par l'utilisateur. J'ai besoin d'une requête pour identifier de telles lignes en collision - quelque chose qui me donnerait l'ID de toutes les lignes dans la collision.

Lors de l'insertion des données dans la base de données que je trouve des collisions avec cette requête:

SELECT ID FROM LEDGER 
WHERE 
    DATE(DATE) = DATE('$timestamp') 
    AND (
     STR_TO_DATE('$starttime','%H:%i:%s') BETWEEN 
      STR_TO_DATE(STARTTIME,'%H:%i:%s') AND STR_TO_DATE(ENDTIME,'%H:%i:%s') OR 
     STR_TO_DATE('$endtime','%H:%i:%s') BETWEEN 
      STR_TO_DATE(STARTTIME,'%H:%i:%s') AND STR_TO_DATE(ENDTIME,'%H:%i:%s') 
    ) AND 
    FNAME = '$fname'"; 

Est-il possible d'y arriver MySQL strictement l'utilisation ou dois-je utiliser PHP pour trouver les collisions? Edit: La solution de Quassnoi m'a aidé à créer la requête exacte dont j'avais besoin. Voici:

SELECT l1.id as id1, l2.id as id2, l1.lname as name1, l2.lname as name2, 
    l1.date as date1, l2.date as name2, l1.starttime as starttime1, 
    l2.starttime as starttime2, l1.endtime as endtime1, l2.endtime as endtime2 
FROM ledger l1 
JOIN ledger l2 
ON  l2.starttime <= l1.endtime 
    AND l2.endtime >= l1.starttime 
    AND l2.lname = l1.lname 
    AND l2.id != l1.id 
    AND DATE(l2.date)=DATE(l1.date) 
+0

Vous pouvez remplacer '' = avec '<' sorte que chaque paire d'enregistrements qui se chevauchent renverrait qu'une seule fois. – Quassnoi

Répondre

2

Vous pouvez émettre cette requête:

SELECT l1.id, l2.id 
FROM ledger l1 
JOIN ledger l2 
ON  ADDTIME(CAST(CAST(l2.date AS DATE) AS DATETIME), l2.starttime) <= ADDTIME(CAST(CAST(l1.date AS DATE) AS DATETIME), l1.endtime) 
     AND ADDTIME(CAST(CAST(l2.date AS DATE) AS DATETIME), l2.endtime) <= ADDTIME(CAST(CAST(l1.date AS DATE) AS DATETIME), l1.starttime) 
     AND l1.id < l2.id 
Questions connexes