Postgresql:标记组的第一行

时间:2017-03-16 05:25:39

标签: sql postgresql conditional case

我有一张这样的表:

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

我选择每个组没有问题,但是我想通过group_id标记每个组的第一个匹配项。然后将其添加为列以标记该行是该组的第一次出现。

例如,Richard为第1组,Enzo为第2组,等等。

我应该可以使用:

         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查询制定条件语句?

2 个答案:

答案 0 :(得分:3)

使用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)    

选择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)

答案 1 :(得分:1)

请检查我的回答,如果逻辑错误

,请告诉我
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