with CTE as (
select
*
,ROW_NUMBER() over (partition by facility_id,name order by created_at asc ) ascrnk
,ROW_NUMBER() over (partition by facility_id,name order by created_at desc ) desrnk
from TestTable
)
select T1.facility_id,T1.name,
T1.value as "First_value",
T1.created_at as "First created_at",
T2.value as "Last_value",
T2.created_at as "Last created_at"
from (
select * from cte
where ascrnk = 1
) T1
left join (
select * from cte
where desrnk = 1
) T2 on T1.facility_id = T2.facility_id and T1.name = T2.name
Result:
| facility_id | name | First_value | First created_at | Last_value | Last created_at |
|-------------|------|-------------|----------------------|------------|----------------------|
| 2011 | A | 200 | 2015-05-30T11:50:17Z | 300 | 2017-05-30T11:50:17Z |
| 2012 | B | 124 | 2015-05-30T11:50:17Z | 195 | 2017-05-30T11:50:17Z |
| 2013 | C | 231 | 2015-05-30T11:50:17Z | 275 | 2017-06-30T11:50:17Z |
| 2014 | D | 279 | 2017-06-30T11:50:17Z | 263 | 2018-06-30T11:50:17Z |
I think this is much simpler using window functions and select distinct
:
select distinct facility_id, name,
first_value(value) over (partition by facility_id, name order by created_at asc) as first_value,
min(created_at) as first_created_at,
first_value(value) over (partition by facility_id, name order by created_at desc) as last_value,
max(created_at) as last_created_at
from t;
No subqueries. No joins.
You can also use arrays to accomplish the same functionality, using group by
. It is a shame that SQL Server doesn't directly support first_value()
as a window function.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.