计算sqlite3中的日期平均值

时间:2018-03-17 18:05:28

标签: sqlite

我知道有很多关于这个问题的话题,但没有一个真正帮助我解决了我的问题。在数据库方面我仍然是一个新的东西,我遇到了这个问题。 我有一个名为tests的表,其中包含两列:id和date。 我想计算几个值之间的平均天数差异。 说select date from tests where id=1,它将为我提供日期列表。我想计算那些日子之间的平均差异。

表“测试”

1|2018-03-13
1|2018-03-01
2|2018-03-13
2|2018-03-01
3|2018-03-13
3|2018-03-01
1|2018-03-17
2|2018-03-17
3|2018-03-17

从id = 1

的测试中选择日期
2018-03-13
2018-03-01
2018-03-17

现在我想计算这三个日期之间的平均天数差异。 可以真的使用一些帮助,谢谢!

编辑: 很抱歉不清楚,我会澄清我的问题。 所以学生们在01/03进行了测试,然后是在13/03,然后在17/03。我想要计算的是测试到测试之间的平均天数差异,所以: 第一到第二之间的差异是12天。第二到第三的差异是4天。 由于我们有两个缺口,因此12 + 6除以2,即8 8。

1 个答案:

答案 0 :(得分:0)

  
      
  • 我希望计算这三个日期之间的平均天数差异。*
  •   

平均差异是指"取所有日期之差的绝对值的平均值"。那是12 + 16 + 4 / 3或10.6667。

We need all combinations of dates。为此,我们需要一个没有重复的自连接。通过选择字段并将on<>一起使用来实现这一目标。

select t1.date, t2.date
from tests as t1
join tests as t2 on t1.id = t2.id and t1.date < t2.date
where t1.id = 1;

2018-03-01|2018-03-13
2018-03-01|2018-03-17
2018-03-13|2018-03-17

既然我们拥有所有组合,我们就能发挥作用。但不是简单地减去日期,SQLite并不支持。首先,将它们转换为Julian Days

sqlite> select julianday(t1.date), julianday(t2.date) from tests as t1 join tests as t2 on t1.id = t2.id and t1.date < t2.date where t1.id = 1;
2458178.5|2458190.5
2458178.5|2458194.5
2458190.5|2458194.5

既然我们有数字,我们可以取差值的绝对值并做平均值。

select avg(abs(julianday(t1.date) - julianday(t2.date)))
from tests as t1
join tests as t2 on t1.id = t2.id and t1.date < t2.date
where t1.id = 1;

更新

  

我想要计算的是测试与测试之间的平均天数差异,因此:第一到第二之间的差异是12天。第二到第三的差异是4天。然后(12 + 4)/ 2 = 8应该是结果。

对于问题的这种扭曲,你想要将每一行与下一行进行比较。你想要一个像这样的表:

2018-03-01|2018-03-13
2018-03-13|2018-03-17

其他数据库具有windowlag等功能来完成此任务。 SQLite没有这个。同样,我们将使用自联接,但我们必须每行执行一次。这是correlated subquery

select t1.date as date, (
    select t2.date
    from tests t2
    where t1.id = t2.id and t2.date > t1.date
    order by t2.date
    limit 1
) as next
from tests t1
where id = 1
  and next is not null

subquery-as-column查找每行的下一个日期。

这有点笨拙,所以让我们把它变成一个视图。然后我们可以将它用作表格。只需取出where id = 1,这样就非常有用。

create view test_and_next as
    select t1.id, t1.date as date, (
        select t2.date
        from tests t2
        where t1.id = t2.id and t2.date > t1.date
        order by t2.date
        limit 1
    ) as next
    from tests t1
    where next is not null

现在,我们可以将test_and_next视为包含iddatenext列的表格。然后它和以前一样:把它们变成朱利安日,减去并取平均值。

select avg(julianday(next) - julianday(date))
from test_and_next
where id = 1;

请注意,当您有两行具有相同日期时,这将会横向移动:SQL无法知道哪个是&#34; next&#34;一。例如,如果在&#34; 2018-03-13&#34;他们都会选择&#34; 2018-03-17&#34;作为&#34; next&#34;之一。

2018-03-01|2018-03-13
2018-03-13|2018-03-17
2018-03-13|2018-03-17

我不确定如何解决这个问题。