我有下表:
+----+------+------+
| id | cat1 | cat2 |
+----+------+------+
| 1 | A | foo |
| 2 | A | foo |
| 3 | A | bar |
| 4 | B | sci |
| 5 | B | ble |
| 6 | B | ble |
+----+------+------+
我想对子类别(cat2)进行排名。
所需结果:
+----+------+------+------+
| id | cat1 | cat2 | res |
+----+------+------+------+
| 1 | A | foo | 1 |
| 2 | A | foo | 1 |
| 3 | A | bar | 2 |
| 4 | B | sci | 1 |
| 5 | B | ble | 2 |
| 6 | B | ble | 2 |
+----+------+------+------+
我将DENSE_RANK与PARTITION BY结合使用来获得以下结果:
+----+------+------+------+
| id | cat1 | cat2 | res |
+----+------+------+------+
| 1 | A | foo | 2 |
| 2 | A | foo | 2 |
| 3 | A | bar | 1 |
| 4 | B | sci | 2 |
| 5 | B | ble | 1 |
| 6 | B | ble | 1 |
+----+------+------+------+
声明:
SELECT DENSE_RANK() OVER (PARTITION BY cat1 ORDER BY cat2 asc) as res, t.*
FROM mytable t
ORDER BY id;
如您所见,我唯一缺少的是结果的顺序。当前,排名基于cat2的字母顺序。但是,我想保留ID给出的顺序(请参阅所需结果)。仅仅更改我的DENSE_RANK的ORDER BY并不能解决问题。
答案 0 :(得分:1)
WITH cte AS ( SELECT MIN(id) id, cat1, cat2
FROM test
GROUP BY cat1, cat2 )
SELECT t1.id,
t1.cat1,
t1.cat2,
DENSE_RANK() OVER (PARTITION BY t1.cat1 ORDER BY t2.id asc) as res
FROM test t1
JOIN cte t2 USING (cat1, cat2)
ORDER BY t1.id;
当然,CTE可能会转换为子查询。
答案 1 :(得分:1)
您可以使用
LAG() OVER (PARTITION BY .. ORDER BY ..)
和SUM() OVER (PARTITION BY .. ORDER BY ..)
分析功能组合:
WITH t2 AS
(
SELECT LAG(cat2,1) OVER (PARTITION BY cat1 ORDER BY id) lg,
t.*
FROM mytable t
ORDER BY id
)
SELECT id, cat1, cat2,
SUM(CASE WHEN lg=cat2 THEN 0 ELSE 1 END) OVER (PARTITION BY cat1 ORDER BY id) as res
FROM t2