MySQL выбирает DATETIME аналогично с точностью до минуты - PullRequest
8 голосов
/ 28 октября 2011

Я должен сопоставить результаты относительно одного и того же времени между двумя таблицами, но временные метки отличаются на несколько секунд из-за того, как они были записаны. Я хотел бы получить результат, как в Пример 1 , но я получаю только значения со звездочкой, как в Пример 2 . Каков наилучший способ удалить секунды из сравнения или выбрать значение, соответствующее ближайшему значению DATETIME?

В настоящее время я использую этот запрос:

SELECT Table1.TimeSTamp1, Table1.Param1, Table2.TimeStamp2, Table2.Param2 
    FROM Table1, Table2 
    WHERE ... conditions for the other parameters of Table1 and Table2... 
    AND Table1.TimeSTamp1 = Table2.TimeStamp2

Любые предложения о наилучшей практике приветствуются.


Пример 1

TimeStamp1          ¦   Param1  ¦   TimeStamp2          ¦   Param2
2011-01-01 00:00:35 ¦   1       ¦   2011-01-01 00:00:35 ¦   a       *
2011-01-01 00:01:35 ¦   2       ¦   2011-01-01 00:01:35 ¦   b
2011-01-01 00:02:37 ¦   3       ¦   2011-01-01 00:02:35 ¦   c
2011-01-01 00:03:31 ¦   4       ¦   2011-01-01 00:03:35 ¦   d
2011-01-01 00:04:32 ¦   5       ¦   2011-01-01 00:04:35 ¦   e
2011-01-01 00:05:38 ¦   6       ¦   2011-01-01 00:05:35 ¦   f
2011-01-01 00:06:36 ¦   7       ¦   2011-01-01 00:06:36 ¦   g       *
2011-01-01 00:07:32 ¦   8       ¦   2011-01-01 00:07:35 ¦   h
2011-01-01 00:08:33 ¦   9       ¦   2011-01-01 00:08:35 ¦   i
2011-01-01 00:09:33 ¦   10      ¦   2011-01-01 00:09:33 ¦   l       *
2011-01-01 00:10:35 ¦   11      ¦   2011-01-01 00:10:35 ¦   m       *
2011-01-01 00:11:29 ¦   12      ¦   2011-01-01 00:11:31 ¦   n

LLL Пример 2

TimeStamp1          ¦   Param1  ¦   TimeStamp2          ¦   Param2
2011-01-01 00:00:35 ¦   1       ¦   2011-01-01 00:00:35 ¦   a
2011-01-01 00:06:36 ¦   7       ¦   2011-01-01 00:06:36 ¦   g
2011-01-01 00:09:33 ¦   10      ¦   2011-01-01 00:09:33 ¦   l
2011-01-01 00:10:35 ¦   11      ¦   2011-01-01 00:10:35 ¦   m

Ответы [ 3 ]

12 голосов
/ 28 октября 2011

Это выражение MySql вернет вам значения DATETIME с обнуленными секундами.

CONVERT(DATE_FORMAT(table.column,'%Y-%m-%d-%H:%i:00'),DATETIME)

Взгляни на это. https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format. Таким образом, вы можете получить такой запрос:

SELECT Table1.TimeSTamp1, Table1.Param1, Table2.TimeStamp2, Table2.Param2 
    FROM Table1
    JOIN Table2 ON  CONVERT(DATE_FORMAT(Table1.TimeStamp1,'%Y-%m-%d-%H:%i:00'),DATETIME)
                 =  CONVERT(DATE_FORMAT(Table2.TimeStamp2,'%Y-%m-%d-%H:%i:00'),DATETIME)
    WHERE ... conditions for the other parameters of Table1 and Table2... 

Но будьте осторожны. Автоматически сгенерированные временные метки похожи на числа с плавающей точкой; когда двое из них оказываются равными друг другу, это просто удача. Усечение ваших временных отметок до минуты может быть нормальным, но вам также может быть лучше вычесть одну временную отметку из другой и сравнить различия (или абсолютные значения разностей).

Кроме того, это соединение будет медленным, потому что оно должно запускать функцию второго усечения для каждого значения, поэтому оно не может использовать какие-либо индексы.

Вы можете вычесть одну временную метку из другой с помощью TIMESTAMPDIFF(). Но будь осторожен. Эта функция корректно работает только на уровне секунд для отметок времени в течение нескольких дней друг от друга; оно изящно переполняется (как я обнаружил с большой болью).

Вы можете попытаться урезать метки времени до минут, когда вы их вставляете. Это позволило бы вам проиндексировать их.

1 голос
/ 28 октября 2011

Вы можете использовать TIMESTAMPDIFF для вычисления разницы в датах и ​​секундах:

SELECT t1.TimeStamp1, t1.Param1, t2.TimeStamp2, t2.Param2
FROM Table1 t1
LEFT JOIN Table2 t2
ON ABS(TIMESTAMPDIFF(SECOND,t1.TimeStamp1,t2.TimeStamp2))<=4
WHERE ...

Отмечая Предупреждение Олли Джонса , я проверил TIMESTAMPDIFF на MySQL версии 5.1.58 и не обнаружил переполнения с метками времени, отличающимися как минимум на 10000 лет. Так что, возможно, эта проблема была исправлена.

1 голос
/ 28 октября 2011
WHERE ...
AND ABS(UNIX_TIMESTAMP(TimeStamp1) - UNIX_TIMESTAMP(TimeStamp2)) < :threshold:

, где threshold - количество секунд, после которого вы больше не хотите совпадения (например, 60 в течение 1 минуты).

...