sqlite - Sqlite / 填充对现有行进行排名的新列
问题描述
我有一个包含以下列的 SQLite 数据库表:
| day | place | visitors |
-------------------------------------
| 2021-05-01 | AAA | 20 |
| 2021-05-01 | BBB | 10 |
| 2021-05-01 | CCC | 3 |
| 2021-05-02 | AAA | 5 |
| 2021-05-02 | BBB | 7 |
| 2021-05-02 | CCC | 2 |
现在我想介绍一个列“排名”,它表示每天访问者的排名。预期的表格如下所示:
| day | place | visitors | Rank |
------------------------------------------
| 2021-05-01 | AAA | 20 | 1 |
| 2021-05-01 | BBB | 10 | 2 |
| 2021-05-01 | CCC | 3 | 3 |
| 2021-05-02 | AAA | 5 | 2 |
| 2021-05-02 | BBB | 7 | 1 |
| 2021-05-02 | CCC | 2 | 3 |
可以使用(伪代码)之类的程序来填充新列 Rank 的数据。
for each i_day in all_days:
SELECT
ROW_NUMBER () OVER (ORDER BY `visitors` DESC) Day_Rank, place
FROM mytable
WHERE `day` = 'i_day'
for each i_place in all_places:
UPDATE mytable
SET rank= Day_Rank
WHERE `Day`='i_day'
AND place = 'i_place'
由于这种逐行更新效率很低,我正在搜索如何使用 SQL 子查询结合 UPDATE 来优化它。
(到目前为止不起作用...)
for each i_day in all_days:
UPDATE mytable
SET rank= (
SELECT
ROW_NUMBER () OVER (ORDER BY `visitors` DESC) Day_Rank
FROM mytable
WHERE `day` = 'i_day'
)
解决方案
visitors
通常,这可以通过计算大于visitors
当前行值的行数的子查询来完成:
UPDATE mytable
SET Day_Rank = (
SELECT COUNT(*) + 1
FROM mytable m
WHERE m.day = mytable.day AND m.visitors > mytable.visitors
);
RANK()
请注意,如果 的值存在关联,则结果实际上是返回的结果visitors
。
请参阅演示。
或者,您可以在 CTE 中计算排名并ROW_NUMBER()
在子查询中使用它:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY day ORDER BY visitors DESC) rn
FROM mytable
)
UPDATE mytable
SET Day_Rank = (SELECT rn FROM cte c WHERE (c.day, c.place) = (mytable.day, mytable.place));
请参阅演示。
或者,如果您的 SQLite 版本是 3.33.0+,您可以使用类似连接的UPDATE...FROM...
语法:
UPDATE mytable AS m
SET Day_Rank = t.rn
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY day ORDER BY visitors DESC) rn
FROM mytable
) t
WHERE (t.day, t.place) = (m.day, m.place);
推荐阅读
- python - 关于 Python vs C++ 和 Java 中的类变量的问题
- c - 尝试初始化结构数组时出现段错误
- video - 如何在切割 MP4 文件的一部分后确定 MP4 文件中哪些偏移量发生了变化
- html - Css - 根据第一个孩子的身高拉伸父块并防止根据第二个孩子的身高拉伸
- git - Git Push 挂起写入对象
- scala - 如何根据火花scala中的N值复制记录
- javascript - 第二次单击后模态未显示在我的反应 boostrap 表中
- sql - 避免对以下查询进行索引扫描?
- python - Pandas:使用行信息创建 3 级多索引
- php - 为什么在我的控制器中添加构造函数时出现错误“无法调用构造函数”