写点什么

row_number 函数的不稳定性

  • 2023-09-05
    广东
  • 本文字数:2718 字

    阅读完需:约 9 分钟

row_number函数的不稳定性

本文分享自华为云社区《row_number函数的不稳定性》,作者: nullptr_ 。


row_number 为窗口函数,用来为各组内数据生成连续排号

基础用法


postgres=# select id,name,age,row_number() over() from test; id | name | age | row_number----+------+-----+------------  2 | 张三 |  13 |          1  3 | 张四 |  16 |          2  3 | 张三 |  14 |          3  1 | 张三 |  12 |          4  3 | 张四 |  15 |          5(5 rows)    
复制代码


postgres=# select id,name,age,row_number() over(order by age) from test; id | name | age | row_number----+------+-----+------------  3 | 张四 |  16 |          5  3 | 张三 |  14 |          3  3 | 张四 |  15 |          4  1 | 张三 |  12 |          1  2 | 张三 |  13 |          2(5 rows)
复制代码


postgres=# select id,name,age,row_number() over(partition by name order by age) from test; id | name | age | row_number----+------+-----+------------  1 | 张三 |  12 |          1  2 | 张三 |  13 |          2  3 | 张三 |  14 |          3  3 | 张四 |  15 |          1  3 | 张四 |  16 |          2(5 rows)
复制代码

特殊用法


postgres=# select * from test1 where id in (1,2,4); id |                                                                                                          info----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------  2 | 张三,12;张三,13;张三,14  1 | 张四,13;张四,16;张四,17  4 | 张十一,14;张十一,13;张十一,16;张十一,146;张十一,136;张十一,166;张十一,46;张十一,36;张十一,66;张十一,246;张十一,236;张十一,26;张十一,36;张十一,76;张十一,17;张十一,13;张十一,15;张十一,19;张十一,10;张十一,6;张十一,966(3 rows)
复制代码


需求:将表中 info 字段转成行,并按照存储顺序生成组内序号。


将字段 info 通过函数 regexp_split_to_table 用分号作为分隔符转成行,通过 split_part 将各行分段输出


postgres=#  select split_part(c.a,',',1) as name, split_part(c.a,',',2) as age from (select regexp_split_to_table(info,';') as a  from test1 where id in (1,2,4)) c;  name  | age--------+----- 张十一 | 14 张十一 | 13 张十一 | 16 张十一 | 146 张十一 | 136 张十一 | 166 张十一 | 46 张十一 | 36 张十一 | 66 张十一 | 246 张十一 | 236 张十一 | 26 张十一 | 36 张十一 | 76 张十一 | 17 张十一 | 13 张十一 | 15 张十一 | 19 张十一 | 10 张十一 | 6 张十一 | 966 张四   | 13 张四   | 16 张四   | 17 张三   | 12 张三   | 13 张三   | 14(27 rows)
复制代码


增加组内行号


postgres=# select split_part(c.a,',',1) as name, split_part(c.a,',',2) as age,row_number() over (partition by name)  from (select regexp_split_to_table(info,';') as a  from test1 where id in (1,2,4)) c;  name  | age | row_number--------+-----+------------ 张三   | 12  |          1 张三   | 13  |          2 张三   | 14  |          3 张十一 | 966 |          1 张十一 | 19  |          2 张十一 | 10  |          3 张十一 | 6   |          4 张十一 | 14  |          5 张十一 | 13  |          6 张十一 | 16  |          7 张十一 | 146 |          8 张十一 | 136 |          9 张十一 | 166 |         10 张十一 | 46  |         11 张十一 | 36  |         12 张十一 | 66  |         13 张十一 | 246 |         14 张十一 | 236 |         15 张十一 | 26  |         16 张十一 | 36  |         17 张十一 | 76  |         18 张十一 | 17  |         19 张十一 | 13  |         20 张十一 | 15  |         21 张四   | 16  |          1 张四   | 17  |          2 张四   | 13  |          3(27 rows)

复制代码


可见行号并非按照存储顺序进行赋值,使用 sequence 进行优化可实现相关需求


postgres=# create sequence test_seq;CREATE SEQUENCEpostgres=# select split_part(c.a,',',1) as name, split_part(c.a,',',2) as age,row_number() over (partition by name order by c.line)  from (select nextval('test_seq') as line, regexp_split_to_table(info,';') as a  from test1 where id in (1,2,4)) c;  name  | age | row_number--------+-----+------------ 张三   | 12  |          1 张三   | 13  |          2 张三   | 14  |          3 张十一 | 14  |          1 张十一 | 13  |          2 张十一 | 16  |          3 张十一 | 146 |          4 张十一 | 136 |          5 张十一 | 166 |          6 张十一 | 46  |          7 张十一 | 36  |          8 张十一 | 66  |          9 张十一 | 246 |         10 张十一 | 236 |         11 张十一 | 26  |         12 张十一 | 36  |         13 张十一 | 76  |         14 张十一 | 17  |         15 张十一 | 13  |         16 张十一 | 15  |         17 张十一 | 19  |         18 张十一 | 10  |         19 张十一 | 6   |         20 张十一 | 966 |         21 张四   | 13  |          1 张四   | 16  |          2 张四   | 17  |          3(27 rows)
复制代码

总结


row_number 的排序是不稳定的,所以不会按照初始顺序进行输出,需要人为给定顺序。

号外!



华为将于 2023 年 9 月 20-22 日,在上海世博展览馆和上海世博中心举办第八届华为全联接大会(HUAWEICONNECT 2023)。本次大会以“加速行业智能化”为主题,邀请思想领袖、商业精英、技术专家、合作伙伴、开发者等业界同仁,从商业、产业、生态等方面探讨如何加速行业智能化。


我们诚邀您莅临现场,分享智能化的机遇和挑战,共商智能化的关键举措,体验智能化技术的创新和应用。您可以:


  • 在 100+场主题演讲、峰会、论坛中,碰撞加速行业智能化的观点

  • 参观 17000 平米展区,近距离感受智能化技术在行业中的创新和应用

  • 与技术专家面对面交流,了解最新的解决方案、开发工具并动手实践

  • 与客户和伙伴共寻商机


感谢您一如既往的支持和信赖,我们热忱期待与您在上海见面。


大会官网:https://www.huawei.com/cn/events/huaweiconnect


欢迎关注“华为云开发者联盟”公众号,获取大会议程、精彩活动和前沿干货。


点击关注,第一时间了解华为云新鲜技术~

发布于: 刚刚阅读数: 6
用户头像

提供全面深入的云计算技术干货 2020-07-14 加入

生于云,长于云,让开发者成为决定性力量

评论

发布
暂无评论
row_number函数的不稳定性_数据库_华为云开发者联盟_InfoQ写作社区