水平选择每个组的第一个和最后一个记录

时间:2018-06-07 04:27:40

标签: sql postgresql eloquent

我有一张像这样的桌子 enter image description here

我想通过facility_id和created_at水平选择每个组的第一个和最后一个记录 需要输出像。我可以垂直做,但需要水平 enter image description here

2 个答案:

答案 0 :(得分:4)

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

<强>结果:

| 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 |

SQL Fiddle Demo Link

答案 1 :(得分:2)

我认为使用窗口函数和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;

没有子查询。没有加入。

您还可以使用group by使用数组来完成相同的功能。遗憾的是,SQL Server不直接支持first_value()作为窗口函数。