Ryan Johnson <ryan.john...@cs.utoronto.ca> writes:

> On 19/10/2012 3:09 PM, Steinar Midtskogen wrote:
>> I have tables with a timestamp (unix time) and columns containing
>> sensor readings which are inserted continuously.  I frequently need to
>> access the most recent values (or NULL if there is no value within the
>> latest, say, hour).  I would like to do something like:

> Is each column associated with a different sensor?

Yes.

> If so, do sensors routinely generate data at the same time and combine their 
> entries?

They usually generate data at the same time, but not always.

> Do sensors emit data frequently?

Usually every 5 minutes, but since the timestamp is unix time, 1
second frequency is supported.

> If any of the above is false, I'd definitely store each column in its
> own table, because the timestamp (the only possible thing to share) is
> replicated anyway.

I have many tables, but each has up to 30 or so values.  The table
division corresponds to the sensor source.  One source will typically
give a bunch of sensor values every 5 minutes (some values might be
NULL, though).  This makes INSERTs trivial.  I suppose I could put
everything in a single table by using UPDATEs, but since the different
sources have different timestamps and even intervals, I've been
thinking that it could make the database consist of mostly NULLs and
explode in size (say, if one table has readings every second, a single
table would have to have 3599 NULLs for each value in a column that
only have one value per hour).

The other extreme, one table for each sensor, has its problems as
well.  Quite often, I'd like to combine several values in one
expression (e.g. subtract one sensor value from another), and that may
be a bit tricky if they are located in different tables, especially if
they don't have the same timestamps.

Anyway, for this purpose I made a module which allows me to combine
several tables into a read-only virtual table similar to a natural
full outer join (I think).  Also, the virtual table will fill out all
missing values using interpolation.  I've also added functionality for
calculating time weighted averages.

It's pretty neat.  I wrote a perl wrapper as well which will look at
the columns that I want to access and it will create the necessary
virtual tables so I don't have to worry about which tables.

So if I want the outside temperature at 14 October 12:12:!2 even if
there is no table entry for that time, I can do:

$ select.pl 'temp_out WHERE unix_time = strftime("%s", "2012-10-14 12:12:12")'
0.93384

And in this case the result is an interpolation using the nearest
entries at 12:10:00 and 12:15:00.  If I want the 24 hour mean around
that time I do:

$ select.pl 'temp_out__avg_24h WHERE unix_time = strftime("%s", "2012-10-14 
12:12:12")'
1.70068 

where the __avg_24h bit is parsed so that an approperiate virtual
table gets created that will give me the 24h average.  And I can
combine columns from different tables, as in this case:

$ select.pl 'temp_in, temp_out, temp_in - temp_out WHERE unix_time = 
strftime("%s", "2012-10-14 12:12:12")'
21.52852    0.93384   20.59468 

where temp_in is in one table and temp_out is in another and neither
table has a row for 12:12:12.  And I can even use different averages
in the same expression, which will cause two virtual tables to become
created behind the scenes:

$ select.pl 'temp_out__avg_1y, temp_out__avg_24h, temp_out__avg_1y - 
temp_out__avg_24h WHERE unix_time = strftime("%s", "2010-01-01 00:00:00")'
4.40974   -7.61093   12.02068 

I'm getting off topic, but the essence is that I want to do flexible
queries with as little typing as possible.  If it can be done in plain
SQL, I'll do that.  If not, if it can be done by using user functions
or modules, I'll do that.  If I can't do that either, I'll add an
outer wrapper translating quasi SQL into SQLite commands.  For the
problem in this thread it seems that I can get away with adding new
aggregate functions.

-- 
Steinar Midtskogen
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to