SQL:计算每天使用日期的总计变化

时间:2019-03-29 09:38:38

标签: mysql sql date

我有下表:

Date        |  Store  |  Total
2018-05-02     ABC       56.98
2018-05-02     DEF       60.34 
2018-05-02     XYZ       46.50
2018-05-03     ABC       80.43
2018-05-03     DEF       70.09
2018-05-03     XYZ       95.98
2018-05-04     ABC       43.52
2018-05-04     DEF       90.23
2018-05-04     XYZ       88.12

我正在尝试创建一个查询,该查询将输出上面的表以及一个名为PrevTotal的附加列,该列对于每个商店在前一天都有其总计。我还想忽略输出表中具有第一个日期(2018-05-02)的所有条目(因为您无法获得第一天的前一个总数)。 例如。输出应为:

Date        |   Code   |   Total   |   PrevTotal 
2018-05-03      ABC        80.43       56.98
2018-05-03      DEF        70.09       60.34
2018-05-03      XYZ        95.98       46.50
2018-05-04      ABC        43.52       80.43
2018-05-04      DEF        90.23       60.34
2018-05-04      XYZ        88.12       95.98      

我不确定如何创建查询来帮助我做到这一点。任何见解都表示赞赏。

5 个答案:

答案 0 :(得分:1)

这对我来说很好。

SELECT s2.*, s1.Total 
FROM Stores s1
LEFT JOIN Stores s2 on s1.Store = s2.Store
     AND DATEDIFF(day, s2.Date, s1.Date) = -1

WHERE s2.Total IS NOT NULL
ORDER BY s1.Date, s1.Store

答案 1 :(得分:0)

您可以像使用第二个最大id一样,但是使用null数据,这样就无法避免,您最好避免在获取/显示时忽略数据:

SELECT tbl2.Date, tbl2.Store, tbl2.total, 
(select total from test_table tbl1 where tbl1.Store = tbl2.Store and tbl1.id < tbl2.id) as prev_Total 
FROM `test_table` tbl2

结果:

Date       |   Store  |  total | prev_Total |
--------------------------------------------
2019-03-21 |   ABC    |  56.98 | NULL       |
--------------------------------------------
2019-03-21 |   DEF    |  60.34 | NULL       |
--------------------------------------------
2019-03-21 |   XYZ    |  46.50 | NULL       |
--------------------------------------------
2019-03-21 |   ABC    |  80.43 | 56.98      |
--------------------------------------------
2019-03-21 |   DEF    |  70.09 | 60.34      |
--------------------------------------------

答案 2 :(得分:0)

如果您使用的是最新版本的MySQL,则可以使用windowing函数使代码更具可读性

实时测试:https://www.db-fiddle.com/f/pKAbtGWF4paTxkbzA8ieST/0

with a as 
(
  select 
      date, store, total, 
      lag(total) over(partition by store
                      order by date) as prev_total
  from t
)
select *
from a
where prev_total is not null
order by date, store

输出:

| date                | store | total | prev_total |
| ------------------- | ----- | ----- | ---------- |
| 2018-05-03 00:00:00 | ABC   | 80.43 | 56.98      |
| 2018-05-03 00:00:00 | DEF   | 70.09 | 60.34      |
| 2018-05-03 00:00:00 | XYZ   | 95.98 | 46.5       |
| 2018-05-04 00:00:00 | ABC   | 43.52 | 80.43      |
| 2018-05-04 00:00:00 | DEF   | 90.23 | 70.09      |
| 2018-05-04 00:00:00 | XYZ   | 88.12 | 95.98      |

答案 3 :(得分:0)

我想以前的总计并不总是从日期开始-1天,但是两天之间可能会有间隔,因此您必须找到每个商店的以前的日期:

select t.*, tt.total prevtotal
from tablename t inner join tablename tt
on 
  tt.store = t.store 
  and 
  tt.date = (
    select max(date) from tablename where store = t.store and date < t.date
  )

请参见demo
结果:

| date       | store | total | prevtotal |
| ---------- | ----- | ----- | --------- |
| 2018-05-03 | ABC   | 80.43 | 56.98     |
| 2018-05-03 | DEF   | 70.09 | 60.34     |
| 2018-05-03 | XYZ   | 95.98 | 46.5      |
| 2018-05-04 | ABC   | 43.52 | 80.43     |
| 2018-05-04 | DEF   | 90.23 | 70.09     |
| 2018-05-04 | XYZ   | 88.12 | 95.98     |

答案 4 :(得分:0)

假设日期是连续的,join会完全满足您的要求:

select t.*, tprev.total as prev_total
from t join
     t tprev
     on tprev.code = t.code and tprev.date = t.date - interval 1 day;

lag()在MySQL 8+中也是可能的。如果索引正确,我不知道哪个会更快。