使用MySQL语句的Joda时间问题

时间:2014-08-11 04:03:27

标签: mysql sql time jodatime

我使用的是Play Framework 2.1.2,JDBC MySQL Connector和Scala 2.10。以下查询是我的问题:

DB.withConnection { implicit connection =>
  SQL("""SELECT SUM(r.dayFrequency) 
         FROM relationships AS r
         WHERE r.id = {id}
         AND
         (r.date BETWEEN {from} AND {to})""").on(
    'id -> id,
    'from -> from,
    'to -> to).as(scalar[Int](bigDecimalToInt).single)
}

它引发了这个例外:

Execution exception[[RuntimeException:     UnexpectedNullableFound(ColumnName(.SUM(r.dayFrequency),Some(SUM(r.dayFrequency))))]]

控制台记录以下查询:

 SELECT SUM(r.dayFrequency)              
 FROM relationships AS r              
 WHERE r.id = 26180              
 AND              
(r.date BETWEEN 2014-08-04 12:00:00.0 AND 2014-08-04 12:00:00.0)

如果我在MySQL Workbench上运行此查询,则返回null,这将确认异常。但是,在查询中进行此更改时,它可以正常工作:

(r.date BETWEEN '2014-08-04' AND '2014-08-04')

为了转换Joda DateTime,我使用了这段代码:Joda DateTime Field on Play Framework 2.0's Anorm

和频率和日期字段如下所示:

date DATE NOT NULL,
dayFrequency INT

任何人都可以帮忙解决这个问题吗?似乎转换有问题。

在第一次POST之后

编辑

从视图中我收到类似2014-08-04的日期字符串,然后在控制器中将它们转换为Joda DateTime,将它们与其他字段进行比较,并在MySQL查询中使用它们,如下所示:

private def clientDateStringToTimestamp(date: String) = {
    val Array(year, month, day) = date.split("-")
    new DateTime(year.toInt, month.toInt, day.toInt, 12, 0, 0).getMillis()
}
new DateTime(clientDateStringToTimestamp("2014-08-04"))

对于MySQL查询,我想仅比较日期部分而不是时间部分。

2 个答案:

答案 0 :(得分:2)

所以我在mysql中做了一个简单的实验:

mysql> create table t (v int);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t values (null);
Query OK, 1 row affected (0.00 sec)

mysql> select sum(v) from t;
+--------+
| sum(v) |
+--------+
|   NULL |
+--------+
1 row in set (0.01 sec)

mysql> insert into t values (1);
Query OK, 1 row affected (0.00 sec)

mysql> select sum(v) from t;
+--------+
| sum(v) |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)

mysql> update t set v = NULL;
Query OK, 1 row affected (0.00 sec)
Rows matched: 2  Changed: 1  Warnings: 0

mysql> select sum(v) from t;
+--------+
| sum(v) |
+--------+
|   NULL |
+--------+
1 row in set (0.00 sec)

所以这告诉我们对null的求和空给我们null,但是对数字求零是给我们数。

我怀疑您的第一个查询(r.date BETWEEN 2014-08-04 12:00:00.0 AND 2014-08-04 12:00:00.0)只返回具有null dayFrequency值的行,其中第二个查询(r.date BETWEEN '2014-08-04' AND '2014-08-04')(在12小时前偏移)返回至少一个非空频率。因此,由于null是可能的,您必须使用scalar[Option[Int]]作为总和,然后使用getOrElse将其变为0。更好的方法是,如果可以,请在数据库dayFrequency中创建NOT NULL DEFAULT 0列。然后它会给你一个0,你就可以总结

答案 1 :(得分:0)