SQL 按连续行的会话对行进行排名
SQL rank rows by sessions of consecutive rows
我有一个 table:
id | emp_id | telecom_id |
----+------------+------------------+
1 | 1 | 1 |
2 | 1 | 1 |
3 | 1 | 1 |
4 | 1 | 2 |
5 | 1 | 3 |
6 | 1 | 3 |
7 | 1 | 1 |
8 | 2 | 5 |
9 | 2 | 1 |
10 | 1 | 1 |
11 | 2 | 1 |
12 | 2 | 1 |
为了方便起见,下面是 table 创建和填充的命令:
CREATE TABLE table1 (
id int NOT NULL,
emp_id varchar(255),
telecom_id varchar(255)
);
insert into table1 (id, emp_id, telecom_id) values(1, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(2, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(3, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(4, '1', '2');
insert into table1 (id, emp_id, telecom_id) values(5, '1', '3');
insert into table1 (id, emp_id, telecom_id) values(6, '1', '3');
insert into table1 (id, emp_id, telecom_id) values(7, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(8, '2', '5');
insert into table1 (id, emp_id, telecom_id) values(9, '2', '1');
insert into table1 (id, emp_id, telecom_id) values(10, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(11, '2', '1');
insert into table1 (id, emp_id, telecom_id) values(12, '2', '1');
我需要以这种 table 的方式对行进行排名,每个 session 行将具有相同的排名。 Session 是一系列具有相等 emp_id 和 telecom_id 的连续行。
例如,第 1-3 行形成一个 session,因为所有 3 行都是 emp_id = 1
和 telecom_id = 1
。第 4 行形成另一个 session。第 5-6 行形成第 3 session 等
用于对数据存储在 table 中的顺序进行排名至关重要。
期望的输出:
id | emp_id | telecom_id | rnk
----+------------+------------------+------
1 | 1 | 1 | 1
2 | 1 | 1 | 1
3 | 1 | 1 | 1
4 | 1 | 2 | 2
5 | 1 | 3 | 3
6 | 1 | 3 | 3
7 | 1 | 1 | 4
8 | 2 | 5 | 5
9 | 2 | 1 | 6
10 | 1 | 1 | 7
11 | 2 | 1 | 8
12 | 2 | 1 | 8
我用 window 函数尝试了各种选项,但没有一个按预期方式工作。
这是产生最接近我想要实现的结果的尝试:
select emp_id, telecom_id, rank()
over(partition by emp_id, telecom_id order by id) as rnk
from table1;
我正在使用 PostgreSQL。
您可以尝试使用lag
window 函数获取pre-Val 并使用条件聚合函数SUM
和window 函数来使您的逻辑。
CREATE TABLE table1 (
id int NOT NULL,
emp_id varchar(255),
telecom_id varchar(255)
);
insert into table1 (id, emp_id, telecom_id) values(1, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(2, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(3, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(4, '1', '2');
insert into table1 (id, emp_id, telecom_id) values(5, '1', '3');
insert into table1 (id, emp_id, telecom_id) values(6, '1', '3');
insert into table1 (id, emp_id, telecom_id) values(7, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(8, '2', '5');
insert into table1 (id, emp_id, telecom_id) values(9, '2', '1');
insert into table1 (id, emp_id, telecom_id) values(10, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(11, '2', '1');
insert into table1 (id, emp_id, telecom_id) values(12, '2', '1');
查询 1:
SELECT id,emp_id,telecom_id,
SUM(CASE WHEN
pretelecomVal = telecom_id
and pre_emp_idVal = emp_id
then 0 else 1 end) over(order by id) rnk
FROM (
select *,
lag(telecom_id) over(partition by emp_id order by id) pretelecomVal,
lag(emp_id) over(order by id) pre_emp_idVal
from table1
) t1
| id | emp_id | telecom_id | rnk |
|----|--------|------------|-----|
| 1 | 1 | 1 | 1 |
| 2 | 1 | 1 | 1 |
| 3 | 1 | 1 | 1 |
| 4 | 1 | 2 | 2 |
| 5 | 1 | 3 | 3 |
| 6 | 1 | 3 | 3 |
| 7 | 1 | 1 | 4 |
| 8 | 2 | 5 | 5 |
| 9 | 2 | 1 | 6 |
| 10 | 1 | 1 | 7 |
| 11 | 2 | 1 | 8 |
| 12 | 2 | 1 | 8 |
我有一个 table:
id | emp_id | telecom_id |
----+------------+------------------+
1 | 1 | 1 |
2 | 1 | 1 |
3 | 1 | 1 |
4 | 1 | 2 |
5 | 1 | 3 |
6 | 1 | 3 |
7 | 1 | 1 |
8 | 2 | 5 |
9 | 2 | 1 |
10 | 1 | 1 |
11 | 2 | 1 |
12 | 2 | 1 |
为了方便起见,下面是 table 创建和填充的命令:
CREATE TABLE table1 (
id int NOT NULL,
emp_id varchar(255),
telecom_id varchar(255)
);
insert into table1 (id, emp_id, telecom_id) values(1, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(2, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(3, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(4, '1', '2');
insert into table1 (id, emp_id, telecom_id) values(5, '1', '3');
insert into table1 (id, emp_id, telecom_id) values(6, '1', '3');
insert into table1 (id, emp_id, telecom_id) values(7, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(8, '2', '5');
insert into table1 (id, emp_id, telecom_id) values(9, '2', '1');
insert into table1 (id, emp_id, telecom_id) values(10, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(11, '2', '1');
insert into table1 (id, emp_id, telecom_id) values(12, '2', '1');
我需要以这种 table 的方式对行进行排名,每个 session 行将具有相同的排名。 Session 是一系列具有相等 emp_id 和 telecom_id 的连续行。
例如,第 1-3 行形成一个 session,因为所有 3 行都是 emp_id = 1
和 telecom_id = 1
。第 4 行形成另一个 session。第 5-6 行形成第 3 session 等
用于对数据存储在 table 中的顺序进行排名至关重要。
期望的输出:
id | emp_id | telecom_id | rnk
----+------------+------------------+------
1 | 1 | 1 | 1
2 | 1 | 1 | 1
3 | 1 | 1 | 1
4 | 1 | 2 | 2
5 | 1 | 3 | 3
6 | 1 | 3 | 3
7 | 1 | 1 | 4
8 | 2 | 5 | 5
9 | 2 | 1 | 6
10 | 1 | 1 | 7
11 | 2 | 1 | 8
12 | 2 | 1 | 8
我用 window 函数尝试了各种选项,但没有一个按预期方式工作。 这是产生最接近我想要实现的结果的尝试:
select emp_id, telecom_id, rank()
over(partition by emp_id, telecom_id order by id) as rnk
from table1;
我正在使用 PostgreSQL。
您可以尝试使用lag
window 函数获取pre-Val 并使用条件聚合函数SUM
和window 函数来使您的逻辑。
CREATE TABLE table1 (
id int NOT NULL,
emp_id varchar(255),
telecom_id varchar(255)
);
insert into table1 (id, emp_id, telecom_id) values(1, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(2, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(3, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(4, '1', '2');
insert into table1 (id, emp_id, telecom_id) values(5, '1', '3');
insert into table1 (id, emp_id, telecom_id) values(6, '1', '3');
insert into table1 (id, emp_id, telecom_id) values(7, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(8, '2', '5');
insert into table1 (id, emp_id, telecom_id) values(9, '2', '1');
insert into table1 (id, emp_id, telecom_id) values(10, '1', '1');
insert into table1 (id, emp_id, telecom_id) values(11, '2', '1');
insert into table1 (id, emp_id, telecom_id) values(12, '2', '1');
查询 1:
SELECT id,emp_id,telecom_id,
SUM(CASE WHEN
pretelecomVal = telecom_id
and pre_emp_idVal = emp_id
then 0 else 1 end) over(order by id) rnk
FROM (
select *,
lag(telecom_id) over(partition by emp_id order by id) pretelecomVal,
lag(emp_id) over(order by id) pre_emp_idVal
from table1
) t1
| id | emp_id | telecom_id | rnk |
|----|--------|------------|-----|
| 1 | 1 | 1 | 1 |
| 2 | 1 | 1 | 1 |
| 3 | 1 | 1 | 1 |
| 4 | 1 | 2 | 2 |
| 5 | 1 | 3 | 3 |
| 6 | 1 | 3 | 3 |
| 7 | 1 | 1 | 4 |
| 8 | 2 | 5 | 5 |
| 9 | 2 | 1 | 6 |
| 10 | 1 | 1 | 7 |
| 11 | 2 | 1 | 8 |
| 12 | 2 | 1 | 8 |