如何查询 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,而不是在选择参数内。
根据您的评论 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
我有一个包含 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,而不是在选择参数内。
根据您的评论 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