Агрегатные функции с условиями

0

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

+------------+---------------------+---------------------+-----------+
|  Logdate   |      Firstart       |      Laststop       | Drivetime |
+------------+---------------------+---------------------+-----------+
| 2018-04-01 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 | 00:36:25  |
| 2018-04-01 | 2018-04-01 07:43:12 | 2018-04-01 09:43:12 | 00:21:23  |
| 2018-04-01 | 2018-04-01 09:53:27 | 2018-04-01 14:45:11 | 00:54:11  |
+------------+---------------------+---------------------+-----------+

Мне приходится группироваться днем и получать минимальное значение Firststart, где оно присутствует.

Если Firststart отсутствует для этого события, значение равно 0000-00-00 00:00:00.

Теперь я должен запросить:

MIN (Firststart) со значением> '0000-00-00 00:00:00' (если присутствует, в противном случае - 0000-00-00 00:00:00 ') и SUM (Drivetime) для каждого регистратора.

Используя этот запрос ниже, я всегда получаю '0000-00-00 00:00:00' как MIN (firstart), но я хочу получить '2018-04-01 07:43:12' за это значение,

SELECT 
 Logdate,
 MIN(Firststart) AS Firststart,
 MAX(Laststop) AS Laststop,
 SEC_TO_TIME(SUM(TIME_TO_SEC(Drivetime))) AS Drivetime
FROM Logevents
WHERE Logdate >= "2018-04-01"
GROUP BY Logdate

Возможно ли это, и если да, то какой правильный синтаксис?

Теги:
aggregate-functions

2 ответа

0
Лучший ответ

Хитрость заключается в том, чтобы использовать NULLIF для переключения до NULL всех строк '0000-00-00 00:00:00' до функции MIN/MAX aggreagate, поскольку она будет исключать их.

После агрегации, если есть нули, мы можем использовать ISNULL чтобы преобразовать их в строку '0000-00-00 00:00:00'.

select 
    Logdate, 
    isnull(MIN(nullif(Firststart, '0000-00-00 00:00:00')), '0000-00-00 00:00:00') Firststart, 
    isnull(MAX(nullif(Laststop, '0000-00-00 00:00:00')), '0000-00-00 00:00:00')  Laststop, 
    cast(dateadd(ss, SUM(datediff(ss, 0, Drivetime)), 0) as time(0)) Drivetime
from x
group by Logdate
  • 0
    Хорошо, спасибо. Хороший подход
  • 0
    пожалуйста
0

Попробуй это:

SELECT Logdate, MAX(Firststart) AS Firststart, MAX(Laststop) AS Laststop,
  SEC_TO_TIME(SUM(TIME_TO_SEC(A.Drivetime))) AS Drivetime
FROM
    (SELECT
      Logdate, MIN(Firststart) AS Firststart, MAX(Laststop) AS Laststop,
      SEC_TO_TIME(SUM(TIME_TO_SEC(Drivetime))) AS Drivetime
    FROM Logevents
    WHERE Firststart>'0000-00-00 00:00:00' 
    GROUP BY Logdate
    UNION
    SELECT
      Logdate, MIN(Firststart) AS Firststart, MAX(Laststop) AS Laststop,
      SEC_TO_TIME(SUM(TIME_TO_SEC(Drivetime))) AS Drivetime
    FROM Logevents
    WHERE Firststart='0000-00-00 00:00:00'
    GROUP BY Logdate) A
GROUP BY A.Logdate;

Посмотрите, как это работает на SQL Fiddle.

  • 0
    Спасибо, но в этом случае первое время в пути 00:36:25 не будет учитываться. Мне нужно иметь также, что в сумме
  • 0
    @ TommySala Я только что обновил свой ответ. Попробуйте еще раз.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню