Php sqlite数据库:获取col1中按总和(col2)排序的每小时项目计数
我有一个大约1000个传感器的网络,将48字节的数据推送到我的服务器,每天最多4次。 服务器维护具有以下结构的sqlite事件数据库: 时间戳 传感器 活动 字节 2021-04-01 01:12:44 ID1 RX_数据 48 2021-04-01 01:15:23 ID2 RX_数据 如果出现错误,则返回0Php sqlite数据库:获取col1中按总和(col2)排序的每小时项目计数,php,sql,sqlite,Php,Sql,Sqlite,我有一个大约1000个传感器的网络,将48字节的数据推送到我的服务器,每天最多4次。 服务器维护具有以下结构的sqlite事件数据库: 时间戳 传感器 活动 字节 2021-04-01 01:12:44 ID1 RX_数据 48 2021-04-01 01:15:23 ID2 RX_数据 如果出现错误,则返回0 我相信以下查询将在一次执行中完成您想要的所有操作:- WITH intermediate AS (SELECT timestamp , CASE W
我相信以下查询将在一次执行中完成您想要的所有操作:-
WITH
intermediate AS (SELECT
timestamp
, CASE WHEN bytes <48 THEN 1 ELSE 0 END AS r1
, CASE WHEN bytes >= 48 AND bytes < 96 THEN 1 ELSE 0 END AS r2
, CASE WHEN bytes >= 96 AND bytes < 144 THEN 1 ELSE 0 END AS r3
, CASE WHEN bytes >= 144 AND bytes < 192 THEN 1 ELSE 0 END AS r4
, CASE WHEN bytes >= 192 THEN 1 ELSE 0 END AS r5
FROM events /* >>>>> INCLUDE YOUR WHERE CLAUSE HERE <<<<< */)
SELECT
strftime('%Y-%m-%d %H:00:00',timestamp) AS 'date time'
, sum(r1) AS '0Bytes'
, sum(r2) AS '48Bytes'
, sum(r3) AS '96Bytes'
, sum(r4) AS '144Bytes'
, sum(r5) AS '192Bytes'
FROM intermediate
GROUP BY strftime('%Y-%m-%d %H',timestamp)
;
WHERE子句尚未包括在内,但已指明了它应该放在哪里。
您只需修改查询以包含WHERE子句,然后替换现有查询。
所有工作都由查询完成。您只需提取报告的行
解释
中间CTE公共表表达式基本上是从事件表创建的临时表。此表包含以下列:-
完全从事件表复制的时间戳
r1-r5列使用CASE-WHEN-THEN-ELSE结束构造,根据WHEN条件将0或1放入列中
然后将CTE用作最终选择查询的输入,您可以拥有多个CTE和
最后一个查询根据查询的YYYY-MM-DD HH部分进行分组
时间戳,对r1-r5中的每一个进行求和,从而计算各个字节范围内的命中数。更改列名以反映要打印/输出/显示的列名
根据报告,YYYY-MM-DD HH后跟:00:00再次作为日期时间列输出
在开始时,基本上是说,在下面的CTE中,做一些不必选择的事情,可以是更新、删除或插入,请参见
范例
结果
每行生成的总值将非常好
以下将包括总数,请参见对上述内容的修改意见
WITH
intermediate AS (SELECT
timestamp
, CASE WHEN bytes <48 THEN 1 ELSE 0 END AS r1
, CASE WHEN bytes >= 48 AND bytes < 96 THEN 1 ELSE 0 END AS r2
, CASE WHEN bytes >= 96 AND bytes < 144 THEN 1 ELSE 0 END AS r3
, CASE WHEN bytes >= 144 AND bytes < 192 THEN 1 ELSE 0 END AS r4
, CASE WHEN bytes >= 192 THEN 1 ELSE 0 END AS r5
, bytes /*<<<<<<<<<< ADDED */
FROM events /* >>>>> INCLUDE YOUR WHERE CLAUSE HERE <<<<< */)
SELECT
strftime('%Y-%m-%d %H:00:00',timestamp) AS 'date time'
, sum(r1) AS '0Bytes'
, sum(r2) AS '48Bytes'
, sum(r3) AS '96Bytes'
, sum(r4) AS '144Bytes'
, sum(r5) AS '192Bytes'
, sum(bytes) AS Total /*<<<<<<<<<< ADDED */
FROM intermediate
GROUP BY strftime('%Y-%m-%d %H',timestamp)
;
结果将是:-
另外,我想让它更通用,数据大小将自动计算出来
这一点都不具体。但是,您可以轻松地以编程方式构建SQL CASE子句和关联的sum子句,然后构建整个查询以供执行。如果我理解正确,结果集中的每一行表示每个组中有多少个传感器。如果是这样,您需要两个级别的聚合,一个在设备/小时级别,另一个在小时级别 内部聚合对传感器一天内的总字节数求和。然后,外部数据仅旋转此数据以获取每个组中的计数:
SELECT yyyymmddh,
SUM(bytes_in_day = 0) as byes_0,
SUM(bytes_in_day = 48) as byes_48,
SUM(bytes_in_day = 96) as byes_96,
SUM(bytes_in_day = 144) as byes_144,
SUM(bytes_in_day = 192) as byes_192,
SUM(bytes_in_day NOT IN (0, 48, 96, 144, 192)) as bytes_other
FROM (SELECT strftime('%Y-%m-%d %H:00:00', timestamp) as yyyymmddhh,
sensor,
SUM(bytes) as bytes_in_hour,
SUM(SUM(bytes)) OVER (PARTITION BY date(timestamp)) as bytes_in_day
FROM events
GROUP BY yyyymmddhh, sensor
) hs
GROUP BY yyyymmddhh;
如果要按天筛选,可以在子查询中添加WHERE子句。在每个总数据大小存储桶中显示传感器计数根本不清楚。在你的查询中,你按传感器分组,得到总数,然后计算什么?总数是多少?发布示例数据,更好地阐明您想要什么:此外,SQLite确实有任何透视功能,因此不可能更通用。在你的例子中,在循环中运行SQL查询,即使在嵌套循环中重新连接,通常也是一个巨大的瓶颈。我无法完全回答您的问题,但我建议:1只连接一次数据库,创建一个资源,并使用此资源而不是shell_exec。。。2只创建一个SQL查询或尽可能少地创建一个SQL查询以返回所有所需的结果,然后循环返回结果。我不知道您的结果是什么。它们是否一整天都在累积?或者他们只是每小时发生的事情?你好,戈登,结果是一整天累积的。我们的想法是跟踪日常数据检索过程,并且能够说,在某一天的12:00,许多传感器发送了48个字节,或者说我们在21:00开始有完整的192个字节的传感器。希望它更清楚。非常感谢米凯特。我可能没有明确说明的一点是:在db中,字节列包含0(在通信错误的情况下)或48。因此,需要从一开始就进行总结,以便能够监控进度。
SELECT yyyymmddh,
SUM(bytes_in_day = 0) as byes_0,
SUM(bytes_in_day = 48) as byes_48,
SUM(bytes_in_day = 96) as byes_96,
SUM(bytes_in_day = 144) as byes_144,
SUM(bytes_in_day = 192) as byes_192,
SUM(bytes_in_day NOT IN (0, 48, 96, 144, 192)) as bytes_other
FROM (SELECT strftime('%Y-%m-%d %H:00:00', timestamp) as yyyymmddhh,
sensor,
SUM(bytes) as bytes_in_hour,
SUM(SUM(bytes)) OVER (PARTITION BY date(timestamp)) as bytes_in_day
FROM events
GROUP BY yyyymmddhh, sensor
) hs
GROUP BY yyyymmddhh;