zoukankan      html  css  js  c++  java
  • database window over 开窗函数

    本文基于 sqlite3 进行测试,准备工作如下

    import sqlite3
    
    conn = sqlite3.connect('window.db')
    cur = conn.cursor()
    
    ##### 原始数据
    sql = '''select * from window;'''
    cur.execute(sql)
    print(cur.fetchall())
    # (0, 10)
    # (1, 11)
    # (2, 12)
    # (2, 13)
    # (2, 13)
    # (2, 15)

    over 用法

    over 需要和 窗口函数 结合使用,语法为 

    function() + over + (partition by order by) as new_column

    相当于在查询时 多输出一列 new_column;

    其中 partition by 相当于分组,group by,order by 相当于排序

    示例

    sql = '''select *, row_number() over (partition by x order by y) from window;'''
    cur.execute(sql)
    print(cur.fetchall())
    ## 先按 x 进行分组,然后按 y 进行排序,最后一列为 每组 排序的 顺序编号
    # (0, 10, 1)
    # (1, 11, 1)
    # (2, 12, 1)
    # (2, 13, 2)
    # (2, 13, 3)    ### 只有 x = 2 时有4个 y,编号 1 2 3 4
    # (2, 15, 4)

    窗口函数

    有很多窗口函数,持续更新吧

    排序 - row_number() rank() dense_rank()

    ## row_number():
    # partition by 可有可无,order by 必须有
    # 相同值有不同的序号
    ## rank():
    # partition by 可有可无,order by 必须有
    # 相同值有相同的序号
    # 相同值接下来的排序会受影响
    ## dense_rank():
    # partition by 可有可无,order by 必须有
    # 相同值有相同的序号
    # 相同值接下来的排序不受影响

    示例

    sql = '''select *, 
        row_number() over (partition by x order by y) as row_number_result,
        rank() over (partition by x order by y) as rank_result,
        dense_rank() over (partition by x order by y) as dense_rank_result
        from window;'''
    cur.execute(sql)
    print(cur.fetchall())
    
    ## 第 3 列 row_number_result,排序 1 2 3 4,不同序号
    ## 第 4 列 rank_result,排序 1 2 2 4,相同值有相同序号,但影响 下一个排序,本应排 3,排成了 4
    ## 第 5 列 dense_rank_result,排序 1 2 2 3,相同值有相同序号,切不影响 下一个排序
    # (0, 10, 1, 1, 1)
    # (1, 11, 1, 1, 1)
    # (2, 12, 1, 1, 1)
    # (2, 13, 2, 2, 2)
    # (2, 13, 3, 2, 2)
    # (2, 15, 4, 4, 3)

    sum

    sql = '''select x, y, sum(y) over (partition by x order by y) from window;'''
    cur.execute(sql)
    # (0, 10, 10)
    # (1, 11, 11)
    # (2, 12, 12)
    # (2, 13, 38)
    # (2, 13, 38)
    # (2, 15, 53)

    其他如 first_value()、last_value()、lag()、lead() 等等

    开窗的窗口范围

    按 value 设置窗口大小

    sql = '''select *, sum(y) over (order by y range between 2 preceding and 2 following ) from window'''
    cur.execute(sql)
    # (0, 10, 33)       ### 10 减2 加2 范围是 8-12,y 处于该范围的数为 10+11+12=33
    # (1, 11, 59)       ### 11 减2 加2 范围是 9-13,y 处于该范围的数为 10+11+12+13+13=59
    # (2, 12, 59)
    # (2, 13, 64)
    # (2, 13, 64)
    # (2, 15, 41)

    按 row 设置窗口大小

    sql = '''select *, sum(y) over (order by y rows between 2 preceding and 2 following ) from window'''
    cur.execute(sql)
    # (0, 10, 33)       ### 上下延伸2行,10+11+12=33
    # (1, 11, 46)       ### 上下延伸2行,10+11+12+13=46
    # (2, 12, 59)       ### 上下延伸2行,10+11+12+13+13=59
    # (2, 13, 64)
    # (2, 13, 53)
    # (2, 15, 41)

    不限制大小

    over(order by salary range between unbounded preceding and unbounded following)或者
    over(order by salary rows between unbounded preceding and unbounded following)

    参考资料:

    https://www.cnblogs.com/cjm123/p/8033639.html  很全

  • 相关阅读:
    Jquery-EasyUI学习2~
    IIS——发布网站
    一致性哈希算法
    利用ZTree链接数据库实现 [权限管理]
    Form表单提交的简要方式
    Redis学习之5种数据类型操作、实现原理及应用场景
    redis对比其余数据库
    ZooKeeper概述(转)
    Zookeeper-Zookeeper可以干什么
    Java内存分配及变量存储位置实例讲解
  • 原文地址:https://www.cnblogs.com/yanshw/p/12909857.html
Copyright © 2011-2022 走看看