在我的Android SQLite数据库中,我有一个日期时间为YYYY-MM-DD HH:MM格式的列。我想要一个查询(或实际上是一个光标),它会给我所有的行,比如说2015年5月。排序是我被卡住的地方。我希望我的结果先按周分解,然后每周按基于其他列的分类。
现在我只是按日期时间列排序,然后是其他列。例如:ORDER BY t.TASKS_DATETIME ASC, s.STATUSES_RANK ASC, t.TASKS_CATEGORY
。但基本上每一行都有一个独特的日期时间值(即使我不关心这种情况下的小时和分钟),所以没有其他排序发生,最终结果不是非常用户友好。排序顺序对于用户查看和理解此数据非常重要。
我考虑过为每个星期做一个单独的select语句,然后执行UNION ALL
来获取月份数据。但是你不能将ORDER BY
子句与UNION
一起使用,因为它会对整个联合进行排序,而不仅仅是内部的单个select语句。更不用说,它非常丑陋。
我想也许我可以在Android / Java端做到并连接多个Cursor对象。但我无法找到任何办法。这里有人知道吗?我已经离开Java几年了,从来没有那种与语言密切相关的东西。
我想也许我可以用某种方式使用SQLite日期函数[https://www.sqlite.org/lang_datefunc.html]。也许在我的选择中添加一个具有一周中的新列。然后我可以按新列排序,然后是我想要的其他排序标准。或者可能有一种方法可以将范围(或简化的日期时间)放入ORDER BY
子句中。但这正在推动我的SQLite技能的界限。这看起来有可能吗?仅供参考,在Android / Java方面,我将此日期时间字符串转换为GregorianCalendar。
我希望有人比我聪明,能指出我的方向!这些选项似乎都不是很好,我无法想到任何其他选项。
如果我无法弄清楚其他任何内容,我会选择UNION
选项。并添加一个" week_of_year"列中的每个select语句用于标识该周,如此处其他联合/排序问题所示。然后排序" week_of_year"列,后面是我的其他排序条件。我已经开始研究这个了。但我休息一下,在这里要求更好的想法,因为我的直觉说必须有更好的方法。但也许不是:)。
作为额外的背景,我认为不相关,但以防万一...
这个可怕的查询正在StickyHeaderList [https://github.com/emilsjolander/StickyListHeaders]中使用,其中周是标题。如果我不按日期时间排序,则标题/周最终会出现故障。有时他们甚至会复制。
我可能会在某些时候编写我自己的替代方案或更改这个StickyHeaderList代码,也许是每周/标题需要一个游标而不是整个月的一个。我可以在Java和SQL中更轻松地处理日期。但是我今天没有足够的资源。我想,最让人头疼的是,多选CAB菜单允许我选择不同的列表。如果你碰巧知道一个简单的解决方法,也许我会这样做,并接受重大的返工,而不是搞清楚这个问题。
更新:有效!
非常感谢@CL给我答案。为了后人和清晰,这里有一些注意事项。
正确答案是:
SELECT ...
FROM ...
ORDER BY strftime('%Y%W', t.TASKS_DATETIME),
s.STATUSES_RANK,
t.TASKS_CATEGORY
如上所述,数周是挑剔的事情。我还需要考虑那些在一周中的不同日期开始的周数的用户。注意,SQLite默认是在 Monday (而不是星期日)启动ween。此外,关键字为day
而非days
,用于计算该偏移量。此外,偏移应该到日期时间的右侧。
这让我失望:
"ORDER BY strftime('%Y %W', t." + TASKS_SCHED_DATETIME + weekOffset + ")," +
"s." + STATUSES_RANK + " ASC, " +
"t." + TASKS_CATEGORY + " DESC "
最终成为:ORDER BY strftime('%Y %W', t.task_sched_datetime, '+5 day' ), s.status_rank ASC, t.tasks_category DESC
weekOffset
在一个小帮助函数中定义:
private String calculateWeekOfset() {
int wkStart = App.getWeekStart();
int offset = 9 - wkStart; // Calendar.MONDAY == 2
return ", '+" + Integer.toString(offset)+ " day' ";
}
我认为这就是全部。再次感谢!
答案 0 :(得分:1)
要从时间戳中提取字段,请使用strftime function。 在这种情况下,您需要一年中的一周,以及年份本身,以使不同年份的日期独特:
SELECT ...
FROM ...
ORDER BY strftime('%Y%W', t.TASKS_DATETIME),
s.STATUSES_RANK,
t.TASKS_CATEGORY
如果您不想在星期一开始一周,请添加或减去适当的天数:
... strftime('%Y%W', t.TASKS_DATETIME, '+1 days'), ...