Postgresql:标记组的第一行

Postgresql : Mark the first row of a group

我有一个 table 这样的:

id | group_id | name
------------------------
1  |    1     | richard
2  |    1     | ray
3  |    2     | enzo
4  |    2     | shiela
5  |    2     | anne

我对每个组 select 没问题,但是我想用 group_id 标记每个组的第一次出现。然后将其添加为列以标记该行是该组的第一次出现。

例如,第 1 组为 Richard,第 2 组为 Enzo,依此类推。

我应该可以使用:

         select
         t.* 
           case
           when (condition)
           ...(boolean result here)
           end as is_first_row
         from t

结果为:

id | group_id | name    |is_first_row
-------------------------------
1  |    1     | richard | t
2  |    1     | ray     | f
3  |    2     | enzo    | t
4  |    2     | shiela  | f
5  |    2     | anne    | f

如何为 select 查询制定条件语句?

使用row_number():

with my_table(id, group_id, name) as (
values
    (1, 1, 'richard'),
    (2, 1, 'ray'),
    (3, 2, 'enzo'),
    (4, 2, 'shiela'),
    (5, 2, 'anne')
)

select *, row_number() over w = 1 as is_first_row
from my_table
window w as (partition by group_id order by id);

 id | group_id |  name   | is_first_row 
----+----------+---------+--------------
  1 |        1 | richard | t
  2 |        1 | ray     | f
  3 |        2 | enzo    | t
  4 |        2 | shiela  | f
  5 |        2 | anne    | f
(5 rows)    

Select row_number() 看看它是如何工作的。行号按 group_id 在分区中计算,即每个 group_id 分别按 id 顺序计算:

with my_table(id, group_id, name) as (
values
    (1, 1, 'richard'),
    (2, 1, 'ray'),
    (3, 2, 'enzo'),
    (4, 2, 'shiela'),
    (5, 2, 'anne')
)

select *, row_number() over w
from my_table
window w as (partition by group_id order by id);

 id | group_id |  name   | row_number 
----+----------+---------+------------
  1 |        1 | richard |          1
  2 |        1 | ray     |          2
  3 |        2 | enzo    |          1
  4 |        2 | shiela  |          2
  5 |        2 | anne    |          3
(5 rows)

请检查我的回答,如果逻辑有任何错误请告诉我

Create Table #Temp(id int,group_id int,name nvarchar(max))

 Insert into #Temp values
 (1,1,'richard')
,(2,1,'ray')
,(3,2,'enzo')
,(4,2,'shiela')
,(5,2,'anne')

Select t2.id,t2.group_id,t2.name,t1.group_id_c, case
when t1.group_id_c=1 then 't'
else 'f'
end  AS is_firstrow from #temp t2 join 
(Select t.*, row_number() over (partition by group_id order by id) as group_id_c from #Temp t ) t1
on t1.id=t2.id