基于DB2中一个月的第一条记录和最后一条记录的字段差异

时间:2019-09-11 09:22:11

标签: db2

如何获取每月记录的第一行和最后一行,以及如何查找同一表上其他字段的差异。例如,我们有一个表“ READING”,我们需要根据每个月的(MAX(READINGDATE)-MIN(READINGDATE))找到READING的差异。

+------------------------------------------------+
+-ASSETNUM+------+READING+------+READINGDATE+----+
-  100            4500           2019-01-02
   100            2800           2019-01-03
   100            1400           2019-01-15
   100            800            2019-01-22
   100            3020           2019-01-29
   100            4800           2019-01-31
   100            2750           2019-02-01
   100            3580           2019-02-08
   100            768            2019-02-19
   100            1890           2019-02-28

预期输出应为

+-----------------------------------------+
+-ASSETNUM+-----+READING+----+READINGDATE-+
   100           300           Jan 2019
   100           -860          Feb 2019

阅读日期字段为DATETIME格式。我知道我们可以处理数据字段的最小值和最大值,但是我不确定如何确定每个月的第一个值和最后一个值的差。

2 个答案:

答案 0 :(得分:1)

您可以使用分析功能first_value()last_value()

select distinct 
  assetnum, 
  last_value(reading) 
    over (partition by ASSETNUM, month(readingdate) 
          order by readingdate
          range between unbounded preceding and unbounded following)
- first_value(reading) 
    over (partition by ASSETNUM, month(readingdate) 
          order by readingdate
          range between unbounded preceding and unbounded following),
  varchar_format(readingdate, 'Mon YYYY')
from readings

dbfiddle link

答案 1 :(得分:0)

尝试一下:

/*
with READING (READING, READINGDATE) as 
(
values 
  (4500, timestamp('2019-01-02', '00.00.00'))
, (2800, timestamp('2019-01-03', '00.00.00'))
, (1400, timestamp('2019-01-15', '00.00.00'))
, ( 800, timestamp('2019-01-22', '00.00.00'))
, (3020, timestamp('2019-01-29', '00.00.00'))
, (4800, timestamp('2019-01-31', '00.00.00'))
, (2750, timestamp('2019-02-01', '00.00.00'))
, (3580, timestamp('2019-02-08', '00.00.00'))
, ( 768, timestamp('2019-02-19', '00.00.00'))
, (1890, timestamp('2019-02-28', '00.00.00'))
)
*/
select mx.READING - mn.READING as READING, g.READINGDATE_MONTH
from 
(
select 
  to_char(READINGDATE, 'Mon YYYY', 'en_US') READINGDATE_MONTH
, year(READINGDATE) READINGDATE_Y
, month(READINGDATE) READINGDATE_M
, min(READINGDATE) as READINGDATE_MIN
, max(READINGDATE) as READINGDATE_MAX
from READING
group by to_char(READINGDATE, 'Mon YYYY', 'en_US'), year(READINGDATE), month(READINGDATE)
) g
join READING mn on mn.READINGDATE = g.READINGDATE_MIN
join READING mx on mx.READINGDATE = g.READINGDATE_MAX
order by g.READINGDATE_Y, g.READINGDATE_M
;