SQLite查询每月的第n天

时间:2016-07-12 07:16:44

标签: sql sqlite datetime date-arithmetic

说,我有下表:

CREATE TABLE Data (
    Id INTEGER PRIMARY KEY,
    Value DECIMAL,
    Date DATE);

由于申请与财务相关,用户可以选择,哪一天是该月的第一天。例如,如果他每个月10日收到工资,他可以将该月的第一天设定为第10天。

我想创建一个查询,它返回用户定义的每月第n天的平均值。例如:

 Date           | Value
 ---------------+------
 10.01.2016     | 10
 11.01.2016     | 15
 10.02.2016     | 20
 11.03.2016     | 10

查询结果应为:

 Day | Average
 ----+--------
 1   | 15
 2   | 12.5

注意,如果用户将第一天设置为第10天,则该月的第9天可能是一个月的第28天,第29天,第30天或第31天(取决于我们正在讨论的月份)。所以这并不像从日期中提取日期一样简单。

2 个答案:

答案 0 :(得分:1)

假设日期值不使用格式dd.mm.yyyy而是使用supported date formats之一,您可以使用built-in date functions来计算此值。

要计算两个日期之间的差异(天数),请将它们转换为使用天数作为数字的日期格式,即Julian天。

获得'基础'一个月的一天,我们可以使用修饰符:

> SELECT julianday('2001-02-11') -
         julianday('2001-02-11', 'start of month', '+10 days') + 2;
2.0

+2是必需的,因为我们添加到月的第1天,而不是第0,我们从1开始计数,而不是0。)

如果日期在十分之前,计算出的值将变为零或负数,我们必须使用前一个月:

> SELECT julianday('2001-02-09') -
         julianday('2001-02-09', 'start of month', '-1 month', '+10 days') + 2;
31.0

将这些结果合并到此表达式中,以计算日期Date n

CASE
WHEN julianday(Date) -
     julianday(Date, 'start of month', '+10 days') + 2 > 0
THEN julianday(Date) -
     julianday(Date, 'start of month', '+10 days') + 2
ELSE julianday(Date) -
     julianday(Date, 'start of month', '-1 month', '+10 days') + 2
END

您可以在查询中使用它:

SELECT CASE...END AS Day,
       AVG(Value) AS Average
FROM Data
GROUP BY Day;

答案 1 :(得分:0)

似乎我发现了一个不同的解决方案:

SELECT avg(Amount),
       strftime("%d", Date, "-9 days") AS day
FROM (
    SELECT sum(Amount) AS Amount,
        strftime("%Y-%m-%d", Date, "start of day") AS Date
    FROM Operations
    GROUP BY strftime("%Y-%m-%d", Date, "start of day")
)
GROUP BY day;

其中" -9天"是这个月的第10个(所以first_day-1)。