tags:

views:

42

answers:

1

I have a MySQL table with the following columns: id(int), date (timestamp), starttime(varchar), endtime(varchar), ...

I need to find time slots that are occupied by two or more rows. Here is an example table

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|

Rows 1 and 3 collide, and need to be corrected by the user. I need a query to identify such colliding rows - something that would give me the ID of all rows in the collision.

When inserting data in the database I find collisions with this query:

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'";

Is there any way to accomplish this strictly using MySQL or do I have to use PHP to find the collisions?

Edit: Quassnoi's sollution helped me create the exact query I was needing. This is it:

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)
+2  A: 

You could issue this query:

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
Quassnoi