Сумма длительностей перекрытия для каждой комбинации 2 внешних ключей в MySQL - PullRequest
0 голосов
/ 04 июля 2011

У меня есть база данных с работниками, станциями и сессиями. Сессия описывает, в какое время какой работник был на какой станции. Мне удалось построить запрос, который дает мне продолжительность перекрытия каждого сеанса.

SELECT 
        sA.station_id,
        sA.worker_id AS worker1, 
        sB.worker_id AS worker2, 
        SEC_TO_TIME(
            TIME_TO_SEC(LEAST(sA.end,sB.end)) - TIME_TO_SEC(GREATEST(sA.start,sB.start))
        ) AS overlap
    FROM 
        `sessions` AS sA, 
        `sessions` AS sB
    WHERE 
            sA.station_id = sb.station_id
        AND 
            sA.station_id = 6
        AND (
                sA.start BETWEEN sB.start AND sB.end
            OR 
                sA.end BETWEEN sB.start AND sB.end
        )

С помощью этого запроса я получаю результат, подобный этому

station_id  worker1     worker2     overlap
6             1               1     09:00:00
6             2               1     02:30:00
6             5               1     00:00:00
6             1               1     09:00:00
6             2               1     01:30:00
6             3               1     09:00:00
...
6             12              3     02:00:00
6             14              3     01:00:00
6             17              3     02:00:00
...

Теперь я хотел бы подвести итог наложения для каждой комбинации worker1 и worker2, чтобы получить общую продолжительность наложения.

Я пробовал разные способы использования SUM () и GROUP BY, но так и не получил желаемого результата.

SELECT 
...
SEC_TO_TIME(
    **SUM**(TIME_TO_SEC(LEAST(sA.end,sB.end)) - TIME_TO_SEC(GREATEST(sA.start,sB.start)))
) AS overlap
...

#has as result
station_id  worker1 worker2 overlap
6   1   1   838:59:59

#in combination with
GROUP BY
    worker1

#i get
station_id  worker1 worker2 overlap
6   1   1   532:30:00
6   2   1   -33:00:00
6   3   1   270:30:00
6   5   1   598:30:00
6   6   1   542:00:00
6   7   1   508:00:00
6   8   5   53:00:00
6   9   1   54:30:00
6   10  1   310:00:00
6   11  1   -108:00:00
6   12  1   593:30:00
6   14  1   97:30:00
6   15  1   -53:30:00
6   17  1   293:30:00

последний результат близок, но мне все еще не хватает многих комбинаций. Я также не понимаю, почему отображается комбинация 8 - 5.

спасибо за вашу помощь (и время читать)

1 Ответ

0 голосов
/ 08 июля 2011

ааааа, простите за мою глупость, решение было довольно простым

....
SUM(((UNIX_TIMESTAMP(LEAST(sA.end,sB.end))-UNIX_TIMESTAMP(GREATEST(sA.start,sB.start)))/3600))
...
GROUP BY station_id, worker1, worker2            
ORDER BY worker1, worker2

Я переключился на использование временных меток и преобразовал их в часы на / 3600, потому что мой прежний использованный подход с TIME_TO_SEC и SEC_TO_TIME использовал только часть TIME поля DATETIME и, таким образом, произвел некоторые неправильные числа. С MySQL 5.5 я мог бы использовать TO_SECONDS, но, к сожалению, мой сервер все еще работает с 5.1.

...