我有一个 SQLite 数据库,包含列
time
、name
、value
。
time
列存储以秒为单位的纪元,例如“1695765399”,并且每隔一秒记录一次。
将有一个预定的触发器在 NZST 12:05(午夜)+5 分钟运行此查询,以便为 SQLite 数据库提供一点空间来记录数据。对于每个唯一的
name
,我需要在 time
列中获取 5 分钟前的 12:00:00 NZST 时间(以秒为单位的纪元)(在 SQLite 数据库中,不会丢失任何秒)。并以 UTC '%Y-%m-%dT%H:%M:%SZ' 格式输出。
创建数据:
import sqlite3
import random
from datetime import datetime, timedelta
conn = sqlite3.connect('your_database.db')
c = conn.cursor()
# Create the table
c.execute('''
CREATE TABLE your_table (
name TEXT,
value REAL,
time INTEGER
)
''')
# Start time at 11:55pm
start_time = datetime.now().replace(hour=23, minute=55, second=0)
# Insert data from 11:55pm to 12:10am
for i in range((10 + 5) * 60): # 10 minutes before and 5 minutes after midnight
current_time = start_time + timedelta(seconds=i)
epoch_time = int(current_time.timestamp())
for name in ['1', '2', '3']:
value = random.random()
c.execute('INSERT INTO your_table VALUES (?, ?, ?)', (name, value, epoch_time))
# Commit the changes and close the connection
conn.commit()
conn.close()
我期望的结果:
utc_time name value
------------------------------------------
xxxxx11:00:00 1 100
xxxxx11:00:00 2 200
也许以下可以作为基础。
无论如何,也许以下内容可能是您想要的基础。
它自己的查询:-
WITH local_utc_modifier(lum) AS
/* CTE (Common Table Expression a temp table) with the difference between local and utc (not sure - is correct but principle IF device is setup accordingly)*/
(SELECT (strftime('%s','now','localtime')) - (strftime('%s','now','UTC')))
SELECT
name,
(SELECT lum FROM local_utc_modifier) AS lum , /* the modifier value: include to demonstrate <<<<<<<<<<EXTRA>>>>>>>>>>*/
strftime('%Y-%m-%dT%H:%M:%SZ',time,'unixepoch','-'||(SELECT * FROM local_utc_modifier)||' seconds') /* output value */ AS time,
value, /* NOTE ARBRITRAY */
max(value) AS maxv, /* include to demonstrate arbrtrary value <<<<<<<<<<EXTRA>>>>>>>>>>*/
min(value) AS minv, /* as prev <<<<<<<<<<EXTRA>>>>>>>>>>*/
avg(value) AS avgv, /* as prev <<<<<<<<<<EXTRA>>>>>>>>>>*/
count() AS number_found /* more than 1!!!! SEE ABOVE RESULTS <<<<<<<<<<EXTRA>>>>>>>>>> */
FROM your_table
/* Only midnight rows to a second */
WHERE strftime('%H:%M:%S',time,'unixepoch','-'||(SELECT * FROM local_utc_modifier)||' seconds') = '00:00:00'
/* MIGHT WANT ADDITIONAL CONDITION JUST FOR CURRENT DATE */
/* Note if only 1 row per name then no need for GROUP BY HOWEVER MUST NOT THEN HAVE aggregate functions (count,max,min,avg) */
GROUP BY name
;
上述演示:-
DROP TABLE IF EXISTS your_table;
CREATE TABLE IF NOT EXISTS your_table (
name TEXT,
value REAL,
time INTEGER
);
/* Insert some testing data */
INSERT INTO your_table (name,value,time)
VALUES
(1,100,1695765399),(2,200,1695765405),(3,300,1695765410),(3,10,1695765415),(2,20,1695765420),
/* these ones are at midnight*/
(1,100,1695765420 + 180),(1,15,1695765600),(2,222,1695765600),(3,333,1695765600),
/* 1 second past midnight */
(5,555,1695765601)
;
SELECT name, value, datetime(time,'unixepoch') AS easyreadtime, time FROM your_table;
WITH local_utc_modifier(lum) AS
/* CTE (Common Table Expression a temp table) with the difference between local and utc (not sure - is correct but principle IF device is setup accordingly)*/
(SELECT (strftime('%s','now','localtime')) - (strftime('%s','now','UTC')))
SELECT
name,
(SELECT lum FROM local_utc_modifier) AS lum , /* the modifier value: include to demonstrate <<<<<<<<<<EXTRA>>>>>>>>>>*/
strftime('%Y-%m-%dT%H:%M:%SZ',time,'unixepoch','-'||(SELECT * FROM local_utc_modifier)||' seconds') /* output value */ AS time,
value, /* NOTE ARBRITRAY */
max(value) AS maxv, /* include to demonstrate arbrtrary value <<<<<<<<<<EXTRA>>>>>>>>>>*/
min(value) AS minv, /* as prev <<<<<<<<<<EXTRA>>>>>>>>>>*/
avg(value) AS avgv, /* as prev <<<<<<<<<<EXTRA>>>>>>>>>>*/
count() AS number_found /* more than 1!!!! SEE ABOVE RESULTS <<<<<<<<<<EXTRA>>>>>>>>>> */
FROM your_table
/* Only midnight rows to a second */
WHERE strftime('%H:%M:%S',time,'unixepoch','-'||(SELECT * FROM local_utc_modifier)||' seconds') = '00:00:00'
/* MIGHT WANT ADDITIONAL CONDITION JUST FOR CURRENT DATE */
/* Note if only 1 row per name then no need for GROUP BY HOWEVER MUST NOT THEN HAVE aggregate functions (count,max,min,avg) */
GROUP BY name
;
DROP TABLE IF EXISTS your_table; /* CLEANUP DEMO ENVIRONMENT */
重要以上均使用AEST时间,因此测试数据需要考虑时区差异。 运行上述命令后,结果为:-
第一次加载的数据SELECT:-
- note the 2 highlighted name **1** rows both are at midnight (to demonstrate GROUP BY and aggregate functions)
聚合函数和 GROUP BY
对于名称 1,number_found(来自
count
函数)显示有 2 行与 WHERE 条件匹配(可能注意大小写)。 GROUP BY 子句定义了将被视为聚合函数所应用的组的行集,请注意,对于组,将输出 1 行。
省略 GROUP BY 子句,如果使用任何聚合函数,则所有输出都被视为 1 组。
如果选择输出一列并且它不受聚合表达式的影响,则提取的值将是组中某一行的值。它是一个任意值(例如,对于提取的值列
15
,它可能是 100
)(显示最大值、最小值和平均值)