2013-10-27 60 views
1

我很努力地理解为什么按照DATE在Rails中SQLite的日期时间列上分组返回nil。我想返回在startdate字段中有值的用户数,按日期分组。在DATE中按DATE分组返回零

任何人都可以帮忙吗?删除以下查询的DATE方面会按照我的预期返回结果。请参阅下面的不同的查询和结果:

User.where("startdate IS NOT NULL").group("DATE(startdate)").count

给人

SELECT COUNT(*) AS count_all, DATE(startdate) AS date_startdate 
FROM "users" 
WHERE (startdate IS NOT NULL) 
GROUP BY DATE(startdate) 

=>{nil=>10}

我会想到的是日期的阵列(例如{“2013年6月4日“=> 3,”2013-06-10“=> 4, ”2013-06-11“=> 3}在下面的查询中没有DATE运算符,结果更符合我的预期,但显然我不想按时分组(在我的实际数据库中) e是在同一日期的不同时间)。

User.where("startdate IS NOT NULL").group("(startdate)").count 

给出

SELECT COUNT(*) AS count_all, (startdate) AS startdate 
FROM "users" 
WHERE (startdate IS NOT NULL) 
GROUP BY (startdate) 

=>{"2013-06-04 17:27:30.553802+0000"=>3, "2013-06-10 09:24:06.207327+0000"=>4, "2013-06-11 12:20:37.745819+0000"=>3}

回答

2

最近date formated string SQLite的期待为您的数据是YYYY-MM-DD HH:MM:SS.SSS

如果你所有的日期都在同一时区,+0000,你可能根本不理DATE功能和比较字符串:

User.where("startdate IS NOT NULL").group("SUBSTR(startdate,1,10)").count 

总之,SQLite不执行日期比较。实际上,DATE函数总是返回TEXT

如果您处理不同的时区(最好在应用程序中尝试处理它们),则可以使用Date/time functions modifiers进行附加计算。

编辑:

由于@chuck.p.lee correctly corrected me,最接近的格式是现在YYYY-MM-DD HH:MM:SS.SSS+HH:MM。所以,你的日期转换成这是很容易使用一些字符串操作(截断子milisecond部分):

SUBSTR(startdate, 1, 23) || SUBSTR(startdate, 27, 3) || ':' || SUBSTR(startdate, 30,2) 

现在,您的查询可能正确地写为:

User.where("startdate IS NOT NULL").group("DATE(SUBSTR(startdate, 1, 23) || SUBSTR(startdate, 27, 3) || ':' || SUBSTR(startdate, 30,2))").count 
+0

辉煌 - 第一个查询完成了这项工作,因为它们都在同一个时区 - 谢谢。仅供参考,第二个抛出错误'语法错误,意外')',期待$结束' - 也许它需要纠正社区?无论如何,非常感谢。 – Nick

+0

双/单引号错误...更正! –

1

转换日期的格式mm/dd/yyyy的再组字符串由字符串

这是如何MS SQL服务器代码将如下所示:

SELECT COUNT(*) AS count_all, convert(varchar(10),startdate, 101) AS date_startdate FROM  "users" WHERE (startdate IS NOT NULL) GROUP BY date_startdate 
+0

但这是SQLite和对于编码日期,“mm/dd/yyyy”是最糟糕的想法! –

-1

你的SQL查询是正确的,并且RoR命令也是如此。

它在Postgresql上正常工作。我认为问题是在sqlite上使用DATE函数。可能是它的大小写敏感,你应该尝试“日期”功能,而不是“日期”,但我不知道这一点。

+0

SQLite不区分大小写。 –

2

date()函数需要的时区,以匹配格式 “[ - +] HH:MM” 或 “Z”:

2013-10-07 08:23:19.120 
2013-10-07T08:23:19.120Z 
2013-10-07 08:23:19.120-04:00 
+0

这不是真的! [http://www.sqlite.org/lang_datefunc.html] –

+0

“格式2到10可以选择后跟一个格式为”[+ - ] HH:MM“或只是”Z“的时区指示符。” – SqliteDog

+0

Ups ...抱歉,您的权利! –