我可以在PHP中解决以下问题,但我想知道是否可以在SQLite中完成。
简化版看起来像这样:我有一个简单的电路。我可以独立打开和关闭红色,绿色和蓝色光。我按照以下步骤记录表中每个灯的以秒为单位的时间和以安培为单位的电流:
| Lamp | On | Off | Current |
|-------|----|:---:|--------:|
| red | 2 | 14 | 3 |
| green | 5 | 8 | 8 |
| blue | 6 | 10 | 2 |
如您所见,它们重叠。如果我想正确地集成电流(以计算能耗),我必须将此表转换为新表,这会增加电流。我得到了下表(手动)和适应的时间:
| T1 | T2 | Sum(Current) | Comment |
|:--:|:--:|-------------:|:--------------:|
| 2 | 5 | 3 | red |
| 5 | 6 | 11 | red+green |
| 6 | 8 | 13 | red+green+blue |
| 8 | 10 | 5 | red+blue |
| 10 | 14 | 3 | red |
任何想法,如果sqlite可以做到这一点?也许是通过创建临时表?
答案 0 :(得分:2)
这相当复杂,但我能够通过几种观点来做到这一点:
create table elec (lamp char(10),on_tm int,off_tm int,current int);
insert into elec values
('red',2,14,3),
('green',5,8,8),
('blue',6,10,2);
create view all_tms as
select distinct on_tm
from elec
union
select distinct off_tm
from elec;
create view all_periods as
select t1.on_tm,
(select min(t2.on_tm)
from all_tms t2
where t2.on_tm > t1.on_tm) off_tm
from all_tms t1
select
all_periods.on_tm,
all_periods.off_tm,
sum(case when elec.on_tm <= all_periods.on_tm
and elec.off_tm >= all_periods.off_tm
then elec.current
else 0
end) total_current,
group_concat(case when elec.on_tm <= all_periods.on_tm
and elec.off_tm >= all_periods.off_tm
then elec.lamp
end) lamps
from
all_periods,
elec
group by
all_periods.on_tm,
all_periods.off_tm
视图将所有开始/停止时间组合成输出中的不同块(2-5,5-6等)。
最终SELECT根据每个时间块计算原始表中的每一行。如果灯泡亮起(开始时间在评估时间开始之前,停止时间在评估时间结束之后),则计算其电流。
答案 1 :(得分:2)
这假定为sufficiently recent SQLite version;对于早期版本,您必须将common table expressions替换为临时views:
WITH all_times(T)
AS (SELECT "On" FROM MyTable
UNION
SELECT Off FROM MyTable),
intervals(T1, T2)
AS (SELECT T,
(SELECT min(T)
FROM all_times AS next_time
WHERE next_time.T > all_times.T) AS T2
FROM all_times
WHERE T2 IS NOT NULL)
SELECT T1,
T2,
(SELECT sum(Current)
FROM MyTable
WHERE T1 >= "On" AND T2 <= Off) AS Current_Sum,
(SELECT group_concat(lamp, '+')
FROM MyTable
WHERE T1 >= "On" AND T2 <= Off) AS Comment
FROM intervals
ORDER BY T1