|
|
|
| Таблица имеет уникальный ключ, состоящий из двух колонок:
1) дата и
2) время суток.
Большей частью, расстояние между строками ровно 5 минут,
но изредка встречаются разрывы во времени.
Все эти разрывы необходимо найти
SELECT * FROM nt AS t1
WHERE NOT EXISTS (
SELECT * FROM nt AS t2
WHERE
TIMESTAMP(t1.date, t1.time) = TIMESTAMP(t2.date, t2.time) + INTERVAL 5 MINUTE
)
|
Так слишком долго работает | |
|
|
|
|
|
|
|
для: Eugene77
(17.06.2012 в 11:45)
| | Ну быстро тут никак не получится.
И вы не уточнили, нужно выводить дату/время перед дыркой или после дырки?
Из вашего запроса я сделал вывод, что после.
Большого объема данных, чтоб проверить скорость нет, так что....
Вот еще два варианта проверьте:
SELECT T1.dt,T1.tm
FROM nt T1 LEFT JOIN nt T2
ON timestamp(T1.dt,T1.tm) = timestamp(T2.dt,T2.tm)+INTERVAL 5 MINUTE
WHERE T2.tm is null
| первую строку в выборке нужно отбросить. Впрочем как и в вашем запросе.
И можно еще так извернуться:
SELECT dt, tm FROM(
SELECT * , @dtm +INTERVAL 5 MINUTE AS nxt, @dtm := timestamp(nt.dt,nt.tm)dtm_val
FROM nt
CROSS JOIN (SELECT @dtm := 0 f1)f1 )T
WHERE nxt<>dtm_val
| но сомневаюсь, что будет быстрее. | |
|
|
|
|
|
|
|
для: Sfinks
(18.06.2012 в 11:40)
| | >И вы не уточнили, нужно выводить дату/время перед дыркой или после дырки?
>Из вашего запроса я сделал вывод, что после.
Мне нужно получить последнюю строку перед дыркой и первую перед ней | |
|
|
|
|
|
|
|
для: Eugene77
(17.06.2012 в 11:45)
| | И вот еще, попробуйте такой вариант:
SELECT dt, tm FROM nt
CROSS JOIN (select 0 x union select 5)x
GROUP BY timestamp(dt,tm)+interval x minute
HAVING max(case x when 5 then 1 end) is null
|
Вот он, возможно, будет немного быстрее!
P.S. Первую строку также нужно отбросить. | |
|
|
|
|
|
|
|
для: Sfinks
(20.06.2012 в 11:19)
| | Первые два варианта - это то же пересечение таблиц, "только другими словами".
А последний вариант я не могу понять, возможно, в нём кроется зерно истины...
не могли бы вы немного подробней раскрыть как работает этот запрос? | |
|
|
|
|
|
|
|
для: Eugene77
(25.06.2012 в 06:46)
| | >Первые два варианта - это то же пересечение таблиц, "только другими словами".
В SQL сравнить разные строки ОДНОЙ таблицы без пересечения НЕ ВОЗМОЖНО.
Так что любое решение будет пересечением.
Вопрос только что с чем пересекать.
Например второе решение - это СОВСЕМ не такое же пересечение, как в первом решении или в Вашем. В нем исходная таблица умножается на таблицу состоящую всего из одной ячейки. И все бы было хорошо и красиво, если бы не необходимость отсева значений по результату выборки. Из-за этого отсева пришлось обернуть результат в еще один подзапрос и на этом весь выигрыш сгорел. И даже стало медленнее из-за того что на выборке из выборки слетели индексы.
>не могли бы вы немного подробней раскрыть как работает этот запрос?
Тут происходит удвоение исходной таблицы за счет умножения ее на таблицу X, которая имеет вид:
-----
| x |
-----
| 0 |
| 5 |
-----
|
В результате каждая строчка новой таблицы встречается 2 раза в виде:
-------------------
| date | time | x |
-------------------
| dt_1 | tm_1 | 0 |
| dt_1 | tm_1 | 5 |
-------------------
|
А чтобы понять что с чем группируется и что после группировки отсеивается, выполните промежуточный запрос, чтобы увидеть данные, с которыми работает мускул перед группировкой и отсевом по HAVING:
SELECT *
, timestamp(dt,tm)+interval x minute gr
, case x when 5 then 1 end cs
FROM nt
CROSS JOIN (select 0 x union select 5)x
|
По другому я объяснить наверно не смогу. | |
|
|
|