Sql 基于小时数的组日期列
我在sqlite数据库中有一个表,我在其中存储有关调用日志的数据。例如,假设我的表如下所示Sql 基于小时数的组日期列,sql,database,sqlite,group-by,android-sqlite,Sql,Database,Sqlite,Group By,Android Sqlite,我在sqlite数据库中有一个表,我在其中存储有关调用日志的数据。例如,假设我的表如下所示 | Calls_count | Calls_duration | Time_slice | Time_stamp | | 10 | 500 | 21 | 1399369269 | | 2 | 88 | 22 | 1399383668 | 这里 Calls\u count是自上次观察
| Calls_count | Calls_duration | Time_slice | Time_stamp |
| 10 | 500 | 21 | 1399369269 |
| 2 | 88 | 22 | 1399383668 |
这里
Calls\u count是自上次观察以来进行的呼叫
Calls\u duration是自上次观察以来呼叫的持续时间,单位为毫秒
时间片表示一周的时间部分。每天分为4部分,每部分6小时,以便
06:00-11:59 | 12:00-17:59 | 18:00- 23.59 | 24:00-05:59 |
Mon| 11 | 12 | 13 | 14 |
Tue| 21 | 22 | 23 | 24 |
Wed| 31 | 32 | 33 | 34 |
Thu| 41 | 42 | 43 | 44 |
Fri| 51 | 52 | 53 | 54 |
Sat| 61 | 62 | 63 | 64 |
Sun| 71 | 72 | 73 | 74 |
当观测/记录插入数据库时,时间戳为unix epoch
现在我想创建一个查询,这样,如果我为一周的开始和结束指定时间戳,结果是168行数据,给我按小时分组的调用总数,这样一周中的每一天就有24行。这是一周内每小时的电话细分
SUM_CALLS | Time_Slice | Hour_of_Week |
10 | 11 | 1 |
0 | 11 | 2 |
....
7 | 74 | 167 |
4 | 74 | 168 |
在上述预期结果示例中
1st row is Monday 06:00-06:59
2nd row is Monday 07:00-07:59
Last row is Sunday 04:00-05:59
由于版本3.8.3,SQLite支持公共表表达式 这是一个可能的解决方案
WITH RECURSIVE
hours(x,y) AS (SELECT CAST(STRFTIME('%s',STRFTIME('%Y-%m-%d %H:00:00', '2014-05-05 00:00:00')) AS INTEGER),
CAST(STRFTIME('%s',STRFTIME('%Y-%m-%d %H:59:59', '2014-05-05 00:00:00')) AS INTEGER)
UNION ALL
SELECT x+3600,y+3600 FROM hours LIMIT 168)
SELECT
COALESCE(SUM(Calls_count),0) AS SUM_CALLS,
CASE CAST(STRFTIME('%w',x,'unixepoch') AS INTEGER)
WHEN 0 THEN 7 ELSE STRFTIME('%w',x,'unixepoch') END
||
CASE
WHEN STRFTIME('%H:%M:%S',x,'unixepoch') BETWEEN '06:00:00' AND '11:59:59' THEN 1
WHEN STRFTIME('%H:%M:%S',x,'unixepoch') BETWEEN '12:00:00' AND '17:59:59' THEN 2
WHEN STRFTIME('%H:%M:%S',x,'unixepoch') BETWEEN '18:00:00' AND '23:59:59' THEN 3
WHEN STRFTIME('%H:%M:%S',x,'unixepoch') BETWEEN '00:00:00' AND '05:59:59' THEN 4
END AS Time_Slice,
((x-(SELECT MIN(x) FROM hours))/3600)+1 AS Hour_of_Week
FROM hours LEFT JOIN call_logs
ON call_logs.time_stamp >= hours.x AND call_logs.time_stamp <= hours.y
GROUP BY Hour_of_Week
ORDER BY Hour_of_Week
;
这是使用SQLite版本3.7.13(不带cte)进行测试的:
DROP VIEW IF EXISTS digit;
CREATE TEMPORARY VIEW digit AS SELECT 0 AS d UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION
SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
;
DROP VIEW IF EXISTS hours;
CREATE TEMPORARY VIEW hours AS SELECT STRFTIME('%s','2014-05-05 00:00:00') + s AS x,
STRFTIME('%s','2014-05-05 00:00:00') + s+3599 AS y
FROM (SELECT (a.d || b.d || c.d) * 3600 AS s FROM digit a, digit b, digit c LIMIT 168)
;
SELECT
COALESCE(SUM(Calls_count),0) AS SUM_CALLS,
CASE CAST(STRFTIME('%w',x,'unixepoch') AS INTEGER)
WHEN 0 THEN 7 ELSE STRFTIME('%w',x,'unixepoch') END
||
CASE
WHEN STRFTIME('%H:%M:%S',x,'unixepoch') BETWEEN '06:00:00' AND '11:59:59' THEN 1
WHEN STRFTIME('%H:%M:%S',x,'unixepoch') BETWEEN '12:00:00' AND '17:59:59' THEN 2
WHEN STRFTIME('%H:%M:%S',x,'unixepoch') BETWEEN '18:00:00' AND '23:59:59' THEN 3
WHEN STRFTIME('%H:%M:%S',x,'unixepoch') BETWEEN '00:00:00' AND '05:59:59' THEN 4
END AS Time_Slice,
((x-(SELECT MIN(x) FROM hours))/3600)+1 AS Hour_of_Week
FROM hours LEFT JOIN call_logs
ON call_logs.time_stamp >= hours.x AND call_logs.time_stamp <= hours.y
GROUP BY Hour_of_Week
ORDER BY Hour_of_Week
;
不幸的是,我不能用我的sqlite数据库来测试这一点,因为它来自Android设备,据我所知,即使在最新的操作系统版本4.4 Kit-Kat中也有sqlite 3.7.11。有没有办法将我的旧SQLite数据库从3.7.x转换为3.8.3?如果不能使用新版本的SQLite,可以尝试不使用cte。我添加了一个新版本。