SQL-запрос: это можно сделать без вложенного запроса?

Запрос, приведенный ниже, работает, но очень затратен для вычислений (существует более 14 тыс. Записей); Можно ли сделать это более эффективно (например, без вложенного запроса)? По сути, он сопоставляет экземпляры в той же таблице, которые представляют команду включения (log1), с первой следующей командой выключения (log2).

SELECT log1.`deviceID`, log1.`timestamp` AS `on`, log2.`timestamp` as `off` 
FROM `HC2_log_raw` log1, `HC2_log_raw` log2 
WHERE log1.`newValue` > 0 AND log1.`oldValue` = 0 AND log2.`newValue` = 0 AND log1.`deviceID` = log2.`deviceID` AND 
    log2.`timestamp` = 
    (SELECT MIN(log3.`timestamp`) 
    FROM `HC2_log_raw` log3 
    WHERE log3.`timestamp` > log1.`timestamp` AND log3.`deviceID` = log1.`deviceID` AND log3.`newValue`=0) 

Спасибо!

2 ответа

Решение

Вы можете попробовать использовать JOIN с функциями GROUP BY и MIN для архивации ожидаемого результата

SELECT log1.`deviceid`, 
       log1.`timestamp`      AS `on`, 
       MIN(log2.`timestamp`) AS `off` 
FROM   `hc2_log_raw` log1 
       INNER JOIN `hc2_log_raw` log2 
               ON log1.`deviceid` = log2.`deviceid` 
                  AND log1.`timestamp` < log2.`timestamp` 
WHERE  log1.`newvalue` > 0 
       AND log1.`oldvalue` = 0 
       AND log2.`newvalue` = 0 
GROUP  BY log1.`deviceid`, log1.`timestamp`

Проверь это. насколько мне известно, where пункт работает лучше, чем присоединиться on состояние.

SELECT log1.`deviceID`
    ,log1.`timestamp` AS `on`
    ,log2.`timestamp` AS `off`
FROM 
`HC2_log_raw` log1
inner join `HC2_log_raw` log2
on 
log1.`deviceID` = log2.`deviceID`
where
(
    log1.`newValue` > 0
AND log1.`oldValue` = 0
AND log2.`newValue` = 0
AND log2.`timestamp` = (
        SELECT MIN(log3.`timestamp`)
        FROM `HC2_log_raw` log3
        WHERE log3.`timestamp` > log1.`timestamp`
            AND log3.`deviceID` = log1.`deviceID`
            AND log3.`newValue` = 0
        )
)
Другие вопросы по тегам