SQLite查询加入一系列日期?

时间:2010-01-11 21:18:37

标签: sql datetime sqlite

我正在使用SQLite。

假设我有一个表sales,其中包含两列datecount,以跟踪我在该日期销售的柠檬水的数量。如果我在某一天没有出售任何柠檬水,我很郁闷,无法在sales表中创建新行。

我想知道在给定日期范围内销售的平均眼镜数量。我可以发出这样的查询:

SELECT AVG(count) FROM sales WHERE date IS BETWEEN '2010-01-04' AND '2010-01-10';

但是,除非表格中包含该范围内的所有日期,否则结果将不准确。我需要一些方法告诉SQLite将丢失的行计为零。

我想如果我能加入日期范围的销售表,那将是理想的。这似乎不太可能,因此从日期范围创建表的简单方法可能是下一个最好的方法。我不想修改销售表,这对于柠檬水摊来说似乎很傻,但在现实生活中更有意义。

正如我上面所说,我正在使用SQLite,所以如果你向我推荐其他数据库,你就没有帮助。也就是说,如果您对其他数据库有更多经验,并认为您的解决方案可以在vanilla SQL中完成,我很乐意听到它。

3 个答案:

答案 0 :(得分:6)

创建一个日历表并加入其中:

这样的事情会:

create table dates (id integer primary key);
insert into dates default values;
insert into dates default values;
insert into dates select null from dates d1, dates d2, dates d3 , dates d4;
insert into dates select null from dates d1, dates d2, dates d3 , dates d4;
alter table dates add date datetime;
update dates set date=date('2000-01-01',(-1+id)||' day');

这将覆盖你到2287-05-20 在日期表中向日期列添加索引不会有害。我的sqlite有点生疏,所以我建议你就此问the manual

编辑:索引代码:

create unique index ux_dates_date on dates (date);

答案 1 :(得分:3)

我认为你需要这样的东西:

SELECT sum(count) / ((strftime('%s','2010-01-10')-strftime('%s','2010-01-04')+86400)/86400)
FROM sales
WHERE date IS BETWEEN '2010-01-04' AND '2010-01-10';

查询通过获取给定日期之间的秒数来计算确切的天数 除以86400(= 24 * 3600)秒。

例如

SELECT (strftime('%s','2010-03-01')-strftime('%s','2010-01-01') + 86400) / 86400

输出60这是正确的值。

查看SQLite的Date And Time Functions.

答案 2 :(得分:1)

您可以使用递归公用表表达式生成一系列日期并加入其中:

WITH RECURSIVE
  cnt(x) AS (
    SELECT 0
    UNION ALL
    SELECT x+1 FROM cnt
    LIMIT (SELECT ((julianday('2010-01-10') - julianday('2010-01-04'))) + 1)
), 
WITH date_series AS (
  SELECT date(julianday('2010-01-04'), '+' || x || ' days') as date 
FROM date_series ds
)
SELECT AVG(COALESCE(s.count, 0)) as avg_sales_count
FROM date_series ds
  LEFT JOIN sales s ON ds.date = s.date

我在这里写了一篇博文,其中包含更多信息:http://www.geekytidbits.com/generate-date-range-sqlite/