Подтвердить что ты не робот

Как сравнить значения sqlite TIMESTAMP

У меня есть база данных Sqlite, в которой я хочу выбрать строки, значение которых в столбце TIMESTAMP до определенной даты. Я бы подумал, что это просто, но я не могу это сделать. Я пробовал это:

SELECT * FROM logged_event WHERE logged_event.CREATED_AT < '2010-05-28 16:20:55'

и различные вариации на нем, например, с функциями даты. Я прочитал http://sqlite.org/lang_datefunc.html и http://www.sqlite.org/datatypes.html и Я ожидал бы, что столбец будет иметь числовой тип, и что сравнение будет выполнено по значению timestamp unix. Совершенно очевидно. Кто может помочь? Если это имеет значение, я пробую это в Sqlite Expert Personal.

Edit:

Вот описание таблицы типов:

CREATE TABLE [logged_event]
(
[id] INTEGER  NOT NULL PRIMARY KEY,
[created_at] TIMESTAMP,
[name] VARCHAR(64),
[data] VARCHAR(512)
);

И тестовые данные:

INSERT INTO table VALUES(1,'2010-05-28T15:36:56+0200','test','test');
INSERT INTO table VALUES(2,'2010-05-28T16:20:49+0200','test','test');
INSERT INTO table VALUES(3,'2010-05-28T16:20:51+0200','test','test');
INSERT INTO table VALUES(4,'2010-05-28T16:20:52+0200','test','test');
INSERT INTO table VALUES(5,'2010-05-28T16:20:53+0200','test','test');
INSERT INTO table VALUES(6,'2010-05-28T16:20:55+0200','test','test');
INSERT INTO table VALUES(7,'2010-05-28T16:20:57+0200','test','test');
4b9b3361

Ответ 1

Проблема связана с тем, как вы вставили данные в таблицу: синтаксис +0200 не соответствует ни одному из SQLite time formats:

  • YYYY-MM-DD
  • ГГГГ-ММ-ДД ЧЧ: ММ
  • ГГГГ-ММ-ДД ЧЧ: ММ: СС
  • ГГГГ-ММ-ДД ЧЧ: ММ: SS.SSS
  • YYYY-MM-DDThh: MM
  • YYYY-MM-ДДTчч: ММ: СС
  • YYYY-MM-DDThh: ММ: СС.ссс
  • HH: MM
  • HH: MM: SS
  • HH: MM: СС.ссс
  • Теперь
  • DDDDDDDDDD

Изменение его для использования формата SS.SSS работает правильно:

sqlite> CREATE TABLE Foo (created_at TIMESTAMP);
sqlite> INSERT INTO Foo VALUES('2010-05-28T15:36:56+0200');
sqlite> SELECT * FROM Foo WHERE foo.created_at < '2010-05-28 16:20:55';
sqlite> SELECT * FROM Foo WHERE DATETIME(foo.created_at) < '2010-05-28 16:20:55';
sqlite> INSERT INTO Foo VALUES('2010-05-28T15:36:56.200');
sqlite> SELECT * FROM Foo WHERE DATETIME(foo.created_at) < '2010-05-28 16:20:55';
2010-05-28T15:36:56.200

Если вы абсолютно не можете изменить формат, когда он вставлен, вам, возможно, придется вернуться к выполнению "умного" и модификации фактической строки (т.е. заменить + на . и т.д.).


(исходный ответ)

Вы не указали, какие данные содержатся в столбце CREATED_AT. Если это действительно дата и время, оно будет правильно сопоставляться со строкой:

sqlite> SELECT DATETIME('now');
2010-05-28 16:33:10
sqlite> SELECT DATETIME('now') < '2011-01-01 00:00:00';
1

Если он хранится как временная метка unix, вам нужно вызвать функцию DATETIME со вторым аргументом как 'unixepoch' для сравнения с строкой:

sqlite> SELECT DATETIME(0, 'unixepoch');
1970-01-01 00:00:00
sqlite> SELECT DATETIME(0, 'unixepoch') < '2010-01-01 00:00:00';
1
sqlite> SELECT DATETIME(0, 'unixepoch') == DATETIME('1970-01-01 00:00:00');
1

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

Ответ 2

Поддержка SQLite для типов даты и времени очень ограничена. Возможно, вам придется использовать собственный метод для хранения информации о времени. По крайней мере, это то, что я сделал.

Вы можете определить свои собственные хранимые функции для выполнения сравнений с помощью API-интерфейса SQLite create_function().

Ответ 3

Насколько я могу судить, вполне разумно включить спецификатор часового пояса; см. текст "Форматы от 2 до 10 могут..." на http://www.sqlite.org/lang_datefunc.html Однако проблема заключается в том, что только функции даты интерпретируют временные метки как даты. Поэтому для фактического сравнения вам нужно либо передать временную метку с помощью функции даты, либо хранить вещи, такие как сравнение строк. Один из подходов заключался бы в том, чтобы закодировать ваше приложение таким образом, чтобы вы вызывали datetime на каждое значение, которое вы вставляете, и на каждое литеральное значение в выражении select. Однако простое включение часового пояса, предложенное в существующем ответе, может быть проще во многих приложениях.