Я запускаю простой код, который проверяет ping и берет IP-адрес от SQL.
Я хочу, чтобы код работал только для тех, кого я не видел сегодня, поэтому каждый запуск будет удалять из списка IP-адреса, которые он уже получил, но команда MySQL не работает для меня.
Это команда, которую я нашел:
select
IP
From
database.devices
where DATE(LastConnected) != Date((now))
Данные, которые я сохраняю в базе данных, используют этот формат:
25-may-18 14:30:21
dd-mm-yy hh:mm:ss
Что случилось? Может, мне нужно взять только дату? 25.5.18? Если да - как я могу это сделать?
You make a mistake in **Date((now))** instead of **Date(now())**
Try this:Given all record instead of today
select IP From database.devices where DATE(LastConnected) != Date(now())
Given all record of today
select IP From database.devices where DATE(LastConnected) = Date(now())
"использование этого формата" заставляет думать, что мы сохраняем значения даты и времени как тип строки (например, VARCHAR
), а не используем тип данных DATETIME
MySQL, который предназначен для хранения значений даты и времени. (Но, возможно, я читаю больше в "использовании этого формата" и причудливом dd-Monthname-two_digit_year, чем это оправдано).
Если мы хотим использовать MySQL date/datetime, мы можем преобразовать значения строк в фактический DATETIME
файл, используя функцию STR_TO_DATE
.
И мы можем проверить выражения в списке выбора, чтобы мы могли видеть, что на самом деле происходит...
SELECT d.lastconnected
, STR_TO_DATE(d.lastconnected,'%d-%b-%y %T') AS lc_datetime_
, DATE(NOW())
, DATE(NOW()) + INTERVAL 1 DAY
FROM database.devices
Когда мы тестируем выражения, мы можем использовать их в предложении WHERE
Чтобы вернуть строки, имеющие последнюю связанную строку, которая представляет дату и время, находящиеся в текущем дне, мы могли бы сделать что-то вроде этого:
SELECT d.lastconnected
, STR_TO_DATE(d.lastconnected,'%d-%b-%y %T') AS lc_datetime_
, ...
FROM database.devices d
WHERE STR_TO_DATE(d.lastconnected,'%d-%b-%y %T') >= DATE(NOW()) + INTERVAL 0 DAY
AND STR_TO_DATE(d.lastconnected,'%d-%b-%y %T') < DATE(NOW()) + INTERVAL 1 DAY
Если dt_lastconnected
был столбцом DATETIME
, наш запрос мог бы использовать эффективную операцию сканирования диапазона по индексу, который dt_lastconnected
как ведущий столбец:
SELECT ...
FROM database.devices d
WHERE d.dt_lastconnected >= DATE(NOW()) + INTERVAL 0 DAY
AND d.dt_lastconnected < DATE(NOW()) + INTERVAL 1 DAY
В: Если я изменил... тип данных [последнего связанного столбца] на таблице - что будет с данными? Нужно ли мне снова вступить? Или это изменит его в одиночку?
Чтобы избежать "вытирания" содержимого последнего связанного столбца, мы можем добавить еще один столбец соответствующего типа и установить значение из существующего столбца.
Если таблица представляет собой набор строк по размерному размеру, мы могли бы сделать
ALTER TABLE database.device ADD dt_lastconnected DATETIME
;
UPDATE database.device
SET dt_lastconnected = STR_TO_DATE(d.lastconnected,'%d-%b-%y %T')
;
Это преобразует любые значения, которые он может. Строки с lastconnected
значениями, которые не могут быть проанализированы в действительное время datetime, будут иметь dt_lastconnected
установленный в NULL.
Если мы хотим заполнить новый столбец в наших инструкциях INSERT, нам нужно будет предоставить значения в соответствующем формате, YYYY-MM-DD HH:MI:SS
например
INSERT INTO databases.device ( ... , dt_lastconnected , ... ) VALUES
( ... , '2018-05-25 18:35:15' , ... )
, ( ... , STR_TO_DATE('25-May-2018 18:35:15','%d-%b-%y %T') , ... )
, ( ... , NOW() , ... )
После исправления кода INSERT мы можем удалить столбец строки и переименовать новый столбец. (Это будет более активно, если lastconnected
- столбец в индексе.)
-- remove old column
ALTER TABLE databases.devices
DROP lastconnected ;
-- rename column
ALTER TABLE databases.devices
CHANGE dt_lastconnected lastconnected DATETIME ;
DATE_FORMAT
чтобы указать свой формат, прежде чем использовать на нем функции даты.