Как эффективно предварительно фильтровать строки в сочетании с объединением? - PullRequest
0 голосов
/ 18 февраля 2019

Мне нужно вычислить метки времени между отфильтрованными строками в таблице.

Я использую объединение на основе полезного ответа на другой вопрос:

StackOverflow: разница между метками времени вдве последовательные строки в одной таблице

Моя проблема состоит в том, что моя таблица содержит смешанные данные из нескольких разных объектов, и я ожидаю, что мне нужно сначала выполнить фильтрацию по "object_id = blah" перед выполнением объединения, потому что еслиЯ не буду предварительно фильтровать, тогда объединение будет отличать временные метки от несвязанных object_id (потому что он просто выглядит последовательно, строка за строкой).

Мне нужно объединение, чтобы выполнить разницу временных отметок на основе предыдущего вхожденияobject_id = blah, а не просто непосредственно предшествующая строка.

Поиск наиболее эффективного решения этого запроса.Заранее спасибо!= D

Я уже пытался добавить WHERE object_id = blah после JOIN, и я получил правильное количество строк, но различия в метках времени все еще основывались только на предыдущей строке в каждой разности меток времени.

Я действительно надеялся, что WHERE будет применяться к исходной таблице до того, как произошло СОЕДИНЕНИЕ, но ясно, что это не так.: - (

SELECT
   t1.scanid, t1.event_id, t1.objectect_id, t1.object_timestamp, t1.object_counter,
   TIMEDIFF(t1.object_timestamp, t2.object_timestamp) AS diff
FROM event_data AS t1
LEFT JOIN event_data AS t2 ON ( t2.scanid = t1.scanid - 1);

--+---------------+--------------+------+-----+----------------------+----------------+
--| Field         | Type         | Null | Key | Default              | Extra          |
--+---------------+--------------+------+-----+----------------------+----------------+
--| scanid        | int(11)      | NO   | PRI | NULL                 | auto_increment |
--| event_id      | int(12)      | NO   |     | NULL                 |                |
--| objectect_id  | int(11)      | NO   |     | NULL                 |                |
--| obj_timestamp | timestamp(3) | NO   |     | CURRENT_TIMESTAMP(3) |                |
--| obj_counter   | int(11)      | YES  |     | -1                   |                |
--+---------------+--------------+------+-----+----------------------+----------------+

И с WHERE object_id = 2:

SELECT
   t1.scanid, t1.event_id, t1.objectect_id, t1.object_timestamp, t1.object_counter,
   TIMEDIFF(t1.object_timestamp, t2.object_timestamp) AS diff
FROM event_data AS t1
LEFT JOIN event_data AS t2 ON ( t2.scanid = t1.scanid - 1)
WHERE t1.object_id = 2;

Вот исходные данные объекта:

+--------+----------+------------+-------------------------+-------------+
| scanid | event_id | object_id  | obj_timestamp           | obj_counter |
+--------+----------+------------+-------------------------+-------------+
|      1 |        1 |          2 | 2019-02-17 13:11:02.425 |           0 |
|      2 |        1 |          0 | 2019-02-17 13:11:08.227 |           0 |
|      3 |        1 |          0 | 2019-02-17 13:11:12.303 |           1 |
|      4 |        1 |          0 | 2019-02-17 13:11:31.383 |           2 |
|      5 |        1 |          0 | 2019-02-17 13:11:32.417 |           3 |
|      6 |        1 |          0 | 2019-02-17 13:11:33.451 |           4 |
|      7 |        1 |          0 | 2019-02-17 13:11:34.839 |           5 |
|      8 |        1 |          0 | 2019-02-17 13:11:35.868 |           6 |
|      9 |        1 |          0 | 2019-02-17 13:12:05.143 |           7 |
|     10 |        1 |          0 | 2019-02-17 13:13:08.733 |           8 |
|     11 |        1 |          0 | 2019-02-17 13:13:11.169 |           9 |
|     12 |        1 |          0 | 2019-02-17 13:13:22.239 |          10 |
|     13 |        1 |          0 | 2019-02-17 13:13:24.256 |          11 |
|     14 |        1 |          0 | 2019-02-17 13:13:26.875 |          12 |
|     15 |        1 |          0 | 2019-02-17 13:13:27.910 |          13 |
|     16 |        1 |          2 | 2019-02-17 13:16:24.326 |           1 |
|     17 |        1 |          2 | 2019-02-17 13:16:25.362 |           2 |
|     18 |        1 |          2 | 2019-02-17 13:19:48.318 |           3 |
|     19 |        1 |          2 | 2019-02-17 13:25:01.604 |           4 |
|     20 |        1 |          2 | 2019-02-17 13:30:17.024 |           5 |
|     21 |        1 |          0 | 2019-02-17 13:39:19.664 |          14 |
|     22 |        1 |          0 | 2019-02-17 13:39:20.696 |          15 |
|     23 |        1 |          2 | 2019-02-17 13:41:12.324 |           6 |
|     24 |        1 |          2 | 2019-02-17 13:41:13.349 |           7 |
|     25 |        1 |          0 | 2019-02-17 13:41:14.381 |          16 |
|     26 |        1 |          0 | 2019-02-17 13:41:17.436 |          17 |
|     27 |        1 |          2 | 2019-02-17 13:41:18.467 |           8 |
|     28 |        1 |          0 | 2019-02-17 13:41:20.503 |          18 |
|     29 |        1 |          0 | 2019-02-17 13:41:21.535 |          19 |
|     30 |        1 |          0 | 2019-02-17 13:41:22.563 |          20 |
|     31 |        1 |          2 | 2019-02-17 13:41:23.591 |           9 |
|     32 |        1 |          2 | 2019-02-17 13:41:24.619 |          10 |
+--------+----------+------------+-------------------------+-------------+
32 rows in set (0.00 sec)

Фактический вывод (безWHERE):

+--------+----------+------------+-------------------------+-------------+--------------+
| scanid | event_id | object_id  | obj_timestamp           | obj_counter | diff         |
+--------+----------+------------+-------------------------+-------------+--------------+
|      1 |        1 |          2 | 2019-02-17 13:11:02.425 |           0 | NULL         |
|      2 |        1 |          0 | 2019-02-17 13:11:08.227 |           0 | 00:00:05.802 |
|      3 |        1 |          0 | 2019-02-17 13:11:12.303 |           1 | 00:00:04.076 |
|      4 |        1 |          0 | 2019-02-17 13:11:31.383 |           2 | 00:00:19.080 |
|      5 |        1 |          0 | 2019-02-17 13:11:32.417 |           3 | 00:00:01.034 |
|      6 |        1 |          0 | 2019-02-17 13:11:33.451 |           4 | 00:00:01.034 |
|      7 |        1 |          0 | 2019-02-17 13:11:34.839 |           5 | 00:00:01.388 |
|      8 |        1 |          0 | 2019-02-17 13:11:35.868 |           6 | 00:00:01.029 |
|      9 |        1 |          0 | 2019-02-17 13:12:05.143 |           7 | 00:00:29.275 |
|     10 |        1 |          0 | 2019-02-17 13:13:08.733 |           8 | 00:01:03.590 |
|     11 |        1 |          0 | 2019-02-17 13:13:11.169 |           9 | 00:00:02.436 |
|     12 |        1 |          0 | 2019-02-17 13:13:22.239 |          10 | 00:00:11.070 |
|     13 |        1 |          0 | 2019-02-17 13:13:24.256 |          11 | 00:00:02.017 |
|     14 |        1 |          0 | 2019-02-17 13:13:26.875 |          12 | 00:00:02.619 |
|     15 |        1 |          0 | 2019-02-17 13:13:27.910 |          13 | 00:00:01.035 |
|     16 |        1 |          2 | 2019-02-17 13:16:24.326 |           1 | 00:02:56.416 |
|     17 |        1 |          2 | 2019-02-17 13:16:25.362 |           2 | 00:00:01.036 |
|     18 |        1 |          2 | 2019-02-17 13:19:48.318 |           3 | 00:03:22.956 |
|     19 |        1 |          2 | 2019-02-17 13:25:01.604 |           4 | 00:05:13.286 |
|     20 |        1 |          2 | 2019-02-17 13:30:17.024 |           5 | 00:05:15.420 |
|     21 |        1 |          0 | 2019-02-17 13:39:19.664 |          14 | 00:09:02.640 |
|     22 |        1 |          0 | 2019-02-17 13:39:20.696 |          15 | 00:00:01.032 |
|     23 |        1 |          2 | 2019-02-17 13:41:12.324 |           6 | 00:01:51.628 |
|     24 |        1 |          2 | 2019-02-17 13:41:13.349 |           7 | 00:00:01.025 |
|     25 |        1 |          0 | 2019-02-17 13:41:14.381 |          16 | 00:00:01.032 |
|     26 |        1 |          0 | 2019-02-17 13:41:17.436 |          17 | 00:00:03.055 |
|     27 |        1 |          2 | 2019-02-17 13:41:18.467 |           8 | 00:00:01.031 |
|     28 |        1 |          0 | 2019-02-17 13:41:20.503 |          18 | 00:00:02.036 |
|     29 |        1 |          0 | 2019-02-17 13:41:21.535 |          19 | 00:00:01.032 |
|     30 |        1 |          0 | 2019-02-17 13:41:22.563 |          20 | 00:00:01.028 |
|     31 |        1 |          2 | 2019-02-17 13:41:23.591 |           9 | 00:00:01.028 |
|     32 |        1 |          2 | 2019-02-17 13:41:24.619 |          10 | 00:00:01.028 |
+--------+----------+------------+-------------------------+-------------+--------------+
32 rows in set (0.01 sec)

И с WHERE object_id = 2:

+--------+----------+------------+-------------------------+-------------+--------------+
| scanid | event_id | object_id  | obj_timestamp           | obj_counter | diff         |
+--------+----------+------------+-------------------------+-------------+--------------+
|      1 |        1 |          2 | 2019-02-17 13:11:02.425 |           0 | NULL         |
|     16 |        1 |          2 | 2019-02-17 13:16:24.326 |           1 | 00:02:56.416 |
|     17 |        1 |          2 | 2019-02-17 13:16:25.362 |           2 | 00:00:01.036 |
|     18 |        1 |          2 | 2019-02-17 13:19:48.318 |           3 | 00:03:22.956 |
|     19 |        1 |          2 | 2019-02-17 13:25:01.604 |           4 | 00:05:13.286 |
|     20 |        1 |          2 | 2019-02-17 13:30:17.024 |           5 | 00:05:15.420 |
|     23 |        1 |          2 | 2019-02-17 13:41:12.324 |           6 | 00:01:51.628 |
|     24 |        1 |          2 | 2019-02-17 13:41:13.349 |           7 | 00:00:01.025 |
|     27 |        1 |          2 | 2019-02-17 13:41:18.467 |           8 | 00:00:01.031 |
|     31 |        1 |          2 | 2019-02-17 13:41:23.591 |           9 | 00:00:01.028 |
|     32 |        1 |          2 | 2019-02-17 13:41:24.619 |          10 | 00:00:01.028 |
+--------+----------+------------+-------------------------+-------------+--------------+
11 rows in set (0.00 sec)

1 Ответ

0 голосов
/ 18 февраля 2019

Судя по вашим данным, кажется, что JOIN подходящее условие для вашей таблицы на самом деле t2.obj_counter = t1.obj_counter - 1 AND t2.object_id = t1.object_id;это обеспечит сравнение только временных отметок, связанных с данным объектом.Таким образом, ваш запрос становится (на основе ваших примеров данных):

SELECT
   t1.scanid, t1.event_id, t1.object_id, t1.obj_timestamp, t1.obj_counter,
   TIMEDIFF(t1.obj_timestamp, t2.obj_timestamp) AS diff
FROM event_data AS t1
LEFT JOIN event_data AS t2 ON t2.obj_counter = t1.obj_counter - 1 AND t2.object_id = t1.object_id
WHERE t1.object_id = 2
ORDER BY t1.obj_counter

Вывод:

scanid  event_id    object_id   obj_timestamp       obj_counter diff
1       1           2           2019-02-17 13:11:02 0           null
16      1           2           2019-02-17 13:16:24 1           00:05:22
17      1           2           2019-02-17 13:16:25 2           00:00:01
18      1           2           2019-02-17 13:19:48 3           00:03:23
19      1           2           2019-02-17 13:25:02 4           00:05:14
20      1           2           2019-02-17 13:30:17 5           00:05:15
23      1           2           2019-02-17 13:41:12 6           00:10:55
24      1           2           2019-02-17 13:41:13 7           00:00:01
27      1           2           2019-02-17 13:41:18 8           00:00:05
31      1           2           2019-02-17 13:41:24 9           00:00:06
32      1           2           2019-02-17 13:41:25 10          00:00:01

Демонстрация на dbfiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...