每月第 n 天的 SQLite 查询
SQLite query for n-th day of month
说,我有以下 table:
CREATE TABLE Data (
Id INTEGER PRIMARY KEY,
Value DECIMAL,
Date DATE);
由于该应用程序与财务相关,因此用户可以选择哪一天是该月的第一天。比如他每个月10号发工资,他可以把这个月的第一天设为10号。
我想创建一个查询,returns 用户定义的每月第 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 号(取决于我们谈论的月份)。所以这不像从日期中提取天数那么简单。
假设日期值不使用 dd.mm.yyyy
格式,而是使用 supported date formats, you can use the built-in date functions 格式之一来计算。
要计算两个日期之间的天数差异,请将它们转换为使用天数作为数字的日期格式,即儒略日。
要获得一个月的 'base' 天,我们可以使用修饰符:
> 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;
好像我同时找到了一个不同的解决方案:
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
)。
说,我有以下 table:
CREATE TABLE Data (
Id INTEGER PRIMARY KEY,
Value DECIMAL,
Date DATE);
由于该应用程序与财务相关,因此用户可以选择哪一天是该月的第一天。比如他每个月10号发工资,他可以把这个月的第一天设为10号。
我想创建一个查询,returns 用户定义的每月第 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 号(取决于我们谈论的月份)。所以这不像从日期中提取天数那么简单。
假设日期值不使用 dd.mm.yyyy
格式,而是使用 supported date formats, you can use the built-in date functions 格式之一来计算。
要计算两个日期之间的天数差异,请将它们转换为使用天数作为数字的日期格式,即儒略日。
要获得一个月的 'base' 天,我们可以使用修饰符:
> 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
:
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;
好像我同时找到了一个不同的解决方案:
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
)。