如何查询 SQLite 数据库以 return 所有 dates/times 之间的 2 个特定 dates/times 以毫秒为单位插入?

How to query SQLite database to return all dates/times between 2 specific dates/times which are inserted as milliseconds?

我有一个包含 4 列的 SQLite 数据库。我使用 "System.currentTimeMillis()" 方法在 COLUMN_DATE 中插入了一个 date/time 值作为毫秒,我想查询 SQLite 数据库以获取 2 个特定日期之间的所有行也表示为毫秒。 此查询也必须包含具有这 2 个特定日期的行。

这是我的 SQLite 数据库:

public static final String CREATE_SQL = "create table " + TABLE_NAME + "(" + COLUMN_ID + " integer primary key autoincrement, " +
        COLUMN_DATE + " integer not null, " + COLUMN_STATUS + " text not null, " + COLUMN_TOTAL + " text not null);";

这是带有插入值的数据库:

我想通过 1578530800000 (ID=2) 作为开始日期和 1578698202000 (ID=5) 作为结束日期来查询 SQLite 数据库,并获取这些特定日期之间的所有行,包括那些日期本身。 意思是我想要 table 作为结果用红色矩形标记。

我尝试查询数据库,但没有得到我期望的结果。 这是我的查询示例:

String[] projection = {Wdatabase.COLUMN_ID, Wdatabase.COLUMN_DATE, Wdatabase.COLUMN_STATUS, Wdatabase.COLUMN_TOTAL};
String selection = Wdatabase.COLUMN_DATE + " >= " + startDate + " AND " + Wdatabase.COLUMN_DATE +" <= " + endDate;

Cursor r = Objects.requireNonNull(getActivity()).getContentResolver().query(DbProvider.CONTENT_URI, projection, selection, null, null, null);

任何人都可以向我解释这里有什么问题吗?

这是我的光标和日志:

while (r.moveToNext()) {

        Log.i("Arguments", "CursorId: " + r.getInt(0));
        Log.i("Arguments", "CursorDate: " + r.getLong(1));
        Log.i("Arguments", "CursorStatus: " + r.getString(2));
        Log.i("Arguments", "CursorTotal: " + r.getString(3));

    }

您的查询有误。您应该将变量放置到 query() 方法而不是第一个 null,而不是在选择参数内。

check this

根据您的评论 2020 年 1 月 9 日星期四 00:00:00 (1578524400000) 至 2020 年 1 月 10 日星期五 00:00:00

那么您不会期望获得 ID 5,因为那是 2020 年 1 月 10 日星期五 23:16:42,这是同一天 但晚一点

因此,如果您想获取从日期到日期的所有行而忽略时间,那么您可以使用等同于 :-

SELECT COLUMN_ID,COLUMN_DATE,COLUMN_STATUS,COLUMN_TOTAL FROM thetable WHERE date(COLUMN_DATE / 1000,'unixepoch') BETWEEN date(1578530800000 / 1000,'unixepoch') AND  date(1578697200000 / 1000,'unixepoch');

所以

String selection = "date(" +Wdatabase.COLUMN_DATE + "/ 1000,'unixepoch') BETWEEN date(" + startDate + "/1000,'unixepoch') AND "date(" + endDate + "/1000,'unixepoch')";

或(按照建议)

String selection = "date(" +Wdatabase.COLUMN_DATE + "/ 1000,'unixepoch') BETWEEN date(?/1000,'unixepoch') AND date(?/1000,'unixepoch')";
Cursor r = Objects.requireNonNull(getActivity()).getContentResolver().query(DbProvider.CONTENT_URI, projection, selection, new String[]{String.valueOf(startDate),String.valueOf(endDate)}, null, null);
  • 因此参数是绑定的(即 WHERE 子句中的每个 ? 都安全地替换为 1 比 1 的值)
  • 注意使用 BEWTEEN 这会稍微简化查询,因为它只需要指定一次列。
  • 如果您想要分钟而不是日期,请使用日期时间而不是日期(出现 3 次)。基本上 / 1000 正在降低毫秒数。
  • 请注意,以上是原理代码,尚未 运行 或测试,因此可能包含一些错误。话说原来的SQL已经用
  • 测试过了

:-

DROP TABLE IF EXISTS thetable;
create table thetable (COLUMN_ID integer primary key autoincrement, COLUMN_DATE integer not null, COLUMN_STATUS text not null, COLUMN_TOTAL text not null);
INSERT INTO thetable (COLUMN_DATE,COLUMN_STATUS,COLUMN_TOTAL) VALUES
    (1578524400000,'enter',0),
    (1578530800000,'exit',1),
    (1578611801022,'enter',2),
    (1578697200000,'enter',3),
    (1578698202000,'exit',1),
    (1578783710000,'enter',2);

SELECT COLUMN_ID,COLUMN_DATE,COLUMN_STATUS,COLUMN_TOTAL, datetime(COLUMN_DATE / 1000,'unixepoch') FROM thetable WHERE date(COLUMN_DATE / 1000,'unixepoch') BETWEEN date(1578530800000 / 1000,'unixepoch') AND  date(1578697200000 / 1000,'unixepoch');
DROP TABLE IF EXISTS thetable;

这导致:-

COLUMN_ID   COLUMN_DATE COLUMN_STATUS   COLUMN_TOTAL    datetime(COLUMN_DATE / 1000,'unixepoch')
2   1578530800000   exit    1   2020-01-09 00:46:40
3   1578611801022   enter   2   2020-01-09 23:16:41
4   1578697200000   enter   3   2020-01-10 23:00:00
5   1578698202000   exit    1   2020-01-10 23:16:42