web-dev-qa-db-ja.com

SQLiteのTIMESTAMP値を比較する方法

TIMESTAMP列の値が特定の日付より前である行を選択するSqliteデータベースがあります。これは簡単だと思いますが、それを成し遂げることはできません。私はこれを試しました:

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

それに日付関数などのさまざまなバリエーションがあります。 http://sqlite.org/lang_datefunc.htmlhttp://www.sqlite.org/datatypes.html を読んだので、列が数値型であり、その比較はUNIXタイムスタンプ値で行われます。ありません。手伝ってくれる人はいますか?問題がある場合は、Sqlite Expert Personalで試してみます。

編集:

タイプテーブルの説明は次のとおりです。

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');
24
Roel

問題は、テーブルにデータを挿入した方法にあります。+0200構文が SQLiteの時間形式 のいずれにも一致しません。

  1. YYYY-MM-DD
  2. YYYY-MM-DD HH:MM
  3. YYYY-MM-DD HH:MM:SS
  4. YYYY-MM-DD HH:MM:SS.SSS
  5. YYYY-MM-DDTHH:MM
  6. YYYY-MM-DDTHH:MM:SS
  7. YYYY-MM-DDTHH:MM:SS.SSS
  8. HH:MM
  9. HH:MM:SS
  10. HH:MM:SS.SSS
  11. 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タイムスタンプとして保存されている場合は、2番目の引数を'unixepoch'としてDATETIME関数を呼び出し、文字列と比較する必要があります。

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

それらのどちらもがあなたの問題を解決しない場合(そしてそれが解決する場合でも!)、常に他の人があなたの問題を再現できるように、いくつかのデータを投稿する必要があります。問題を再現する元のデータのサブセットを自由に考え出すこともできます。

44
Mark Rushakoff

SQLiteの日付/時刻型のサポートは非​​常に制限されています。時間情報を維持するために、独自の方法をロールする必要がある場合があります。少なくとも、それは私がやったことです。

SQLite create_function()APIを使用して、比較を行うための独自のストアド関数を定義できます。

1
J. Polfer

私が知ることができるように、タイムゾーン指定子を含めることは完全に合理的です。 「フォーマット2から10まで…」というテキストを参照してください。 at http://www.sqlite.org/lang_datefunc.html ただし、問題は、日付関数のみがタイムスタンプを日付として解釈することです。したがって、実際の比較では、日付関数を介してタイムスタンプを渡すか、文字列比較が機能するように格納する必要があります。 1つのアプローチは、selectステートメントの挿入するすべての値とリテラル値ごとにdatetimeを呼び出すようにアプリケーションをコーディングすることです。ただし、多くのアプリケーションでは、既存の回答で提案されているタイムゾーンを含めない方が簡単な場合があります。

0
Sam Hartman