根据月份和年份选择数据

时间:2020-01-02 04:23:09

标签: sqlite flutter dart flutter-moor

我们在2019-10-09T15:29:28.000+08:00中以以下格式Moor将日期作为字符串存储在created_at列中。

我们想编写一个选择查询,以检索月份为10月而年份为2019的数据。

 Future<ABC> selectReadingBasedOnMonth(
      int month, int year) {
    return (select(abcs)
          ..where((t) {
            final sqliteDate = FunctionCallExpression<DateTime, DateTimeType>(
                'date', [t.createdAt]);

            return sqliteDate.year.equals(year) &
                sqliteDate.month.equals(month);
          }))
        .getSingle();
  }

但是我们没有任何数据。这是显示在日志中的查询

I / flutter(12004):停泊:已发送SELECT * FROM abcs WHERE (CAST(strftime(“%Y”,date(created_at),“ unixepoch”)AS INTEGER))=? AND(CAST(strftime(“%m”,date(created_at),“ unixepoch”)AS INTEGER))= ?;带有args [2019,10]

2 个答案:

答案 0 :(得分:1)

unixepoch 修饰符只能与仅数字的日期/时间字符串一起使用。

“ unixepoch”修饰符(11)仅在紧跟在 以DDDDDDDDDD格式的时间字符串。

此修饰符导致 DDDDDDDDDD不能正常解释为儒略日数 会是,但是作为Unix Time-自1970年以来的秒数。

如果 “ unixepoch”修饰符不遵循以下格式的时间字符串 DDDDDDDDDD,表示自1970年以来的秒数,如果 其他修饰符将“ unixepoch”修饰符与之前的修饰符分开 DDDDDDDDDD,则行为未定义。

对于之前的SQLite版本 3.16.0(2017-01-02),“ unixepoch”修饰符仅适用于0000-01-01 00:00:00到5352-11-01 10:52:47之间的日期( -62167219200到106751991167)。

Date And Time Functions

例如,考虑以下内容(根据您的查询):-

DROP TABLE IF EXISTS abcs;
CREATE TABLE IF NOT EXISTS abcs (created_at TEXT);
INSERT INTO abcs VALUES ('2019-10-09T15:29:28.000+08:00');

SELECT *, 
    CAST(strftime('%Y', date(created_at)/*, 'unixepoch'*/) AS INTEGER) AS year_nounixepoch,
    CAST(strftime('%m', date(created_at)/*, 'unixepoch'*/) AS INTEGER) AS month_nounixepoch,
    CAST(strftime('%Y', date(created_at), 'unixepoch') AS INTEGER) AS year_invalid,
    CAST(strftime('%m', date(created_at), 'unixepoch') AS INTEGER) AS month_invalid,

    CAST(strftime('%Y', strftime('%s',date(created_at)), 'unixepoch') AS INTEGER) AS year_unixepoch,
    CAST(strftime('%m', strftime('%s',date(created_at)), 'unixepoch') AS INTEGER) AS month_unixepoch

FROM abcs 
WHERE CAST(strftime('%Y', strftime('%s',date(created_at)), 'unixepoch') AS INTEGER) = 2019 AND CAST(strftime('%m', strftime('%s',date(created_at)), 'unixepoch') AS INTEGER) = 10;
DROP TABLE IF EXISTS abcs; /* cleanup test environment */ 
  • 请注意,单引号已用于替换双引号,这将是正确的SQL,尽管这种差异可能是由于消息的输出方式所致。

结果为:-

enter image description here

  • 即在使用 unixepoch 修饰符的地方,由于日期/时间不只是数字,因此结果为null。
  • 通过strftime('%s',..... unixepoch 进行选择的条件将按预期工作。

答案 1 :(得分:0)

感谢simolus3提供的answer

 final asDate = FunctionCallExpression('date', [t.createdAt]);
 final year = FunctionCallExpression<String, StringType>(
      'strftime', [const Constant<String, StringType>('%Y'), asDate]);
 final month = FunctionCallExpression<String, StringType>(
      'strftime', [const Constant<String, StringType>('%m'), asDate]);

  return year.equals('2019') & month.equals('07');
相关问题