如何获取每月记录的第一行和最后一行,以及如何查找同一表上其他字段的差异。例如,我们有一个表“ 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格式。我知道我们可以处理数据字段的最小值和最大值,但是我不确定如何确定每个月的第一个值和最后一个值的差。
答案 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
答案 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
;