zoukankan      html  css  js  c++  java
  • 另一种中位数求法

    我在 https://www.cnblogs.com/xiandedanteng/p/12637767.html 里谈到过两种中位数求法,我又找出了一种新的中位数求法,核心解法仍是正序和逆序序列。

    如果存在奇数个元素,观察其seq,revseq和ceil三值,你将发现中值就是seq等于ceil那条,或是revseq等于ceil那条:

    SQL> select
      2  id,salary,rank() over (order by salary asc) as seq,rank() over (order by salary desc) as revseq,(select ceil(count(*)/2) from tb_coder1) as ceil
      3  from tb_coder1 order by salary;
    
            ID     SALARY        SEQ     REVSEQ       CEIL
    ---------- ---------- ---------- ---------- ----------
             5       3083          1          9          5
             6       6548          2          8          5
             4       9057          3          7          5
             8       9521          4          6          5
             3      11458          5          5          5
             9      14775          6          4          5
             1      16292          7          3          5
             2      17009          8          2          5
             7      18825          9          1          5

    如果存在偶数个元素,再观察seq,revseq和ceil三值,你将发现中值就是seq或是revseq等于ceil那两条:

    SQL> select
      2  id,salary,rank() over (order by salary asc) as seq,rank() over (order by salary desc) as revseq,(select ceil(count(*)/2) from tb_coder2) as ceil
      3  from tb_coder2 order by salary;
    
            ID     SALARY        SEQ     REVSEQ       CEIL
    ---------- ---------- ---------- ---------- ----------
             3       3396          1         10          5
             1       3682          2          9          5
             5       5029          3          8          5
             9       5859          4          7          5
             7       9428          5          6          5
             4       9691          6          5          5
             6      13613          7          4          5
            10      14366          8          3          5
             2      16375          9          2          5
             8      19127         10          1          5
    
    已选择10行。

    于是,最终的sql可以出来了:

    select avg(a.salary) from
    (select 
    id,salary,rank() over (order by salary asc) as seq,rank() over (order by salary desc) as revseq,(select ceil(count(*)/2) from tb_coder1) as ceil 
    from tb_coder2 order by salary) a
    where a.seq=a.ceil or a.revseq=a.ceil

    注意,有时需要把rank函数替换成row_number函数:

    select avg(a.salary) from
    (select 
    id,salary,row_number() over (order by salary asc) as seq,row_number() over (order by salary desc) as revseq,(select ceil(count(*)/2) from tb_employee) as ceil 
    from tb_employee) a
    where a.seq=a.ceil or a.revseq=a.ceil

    对于这两个函数的细微差别我目前还有欠缺的地方。

    对于奇数行,结果是:

    SQL> select
      2  id,salary,rank() over (order by salary asc) as seq,rank() over (order by salary desc) as revseq,(select ceil(count(*)/2) from tb_coder1) as ceil
      3  from tb_coder1 order by salary;
    
            ID     SALARY        SEQ     REVSEQ       CEIL
    ---------- ---------- ---------- ---------- ----------
             5       3083          1          9          5
             6       6548          2          8          5
             4       9057          3          7          5
             8       9521          4          6          5
             3      11458          5          5          5
             9      14775          6          4          5
             1      16292          7          3          5
             2      17009          8          2          5
             7      18825          9          1          5
    
    已选择9行。
    
    SQL> select avg(a.salary) from
      2  (select
      3  id,salary,rank() over (order by salary asc) as seq,rank() over (order by salary desc) as revseq,(select ceil(count(*)/2) from tb_coder1) as ceil
      4  from tb_coder1 order by salary) a
      5  where a.seq=a.ceil or a.revseq=a.ceil;
    
    AVG(A.SALARY)
    -------------
            11458

    对于偶数行,结果是:

    SQL> select
      2  id,salary,rank() over (order by salary asc) as seq,rank() over (order by salary desc) as revseq,(select ceil(count(*)/2) from tb_coder2) as ceil
      3  from tb_coder2 order by salary;
    
            ID     SALARY        SEQ     REVSEQ       CEIL
    ---------- ---------- ---------- ---------- ----------
             3       3396          1         10          5
             1       3682          2          9          5
             5       5029          3          8          5
             9       5859          4          7          5
             7       9428          5          6          5
             4       9691          6          5          5
             6      13613          7          4          5
            10      14366          8          3          5
             2      16375          9          2          5
             8      19127         10          1          5
    
    已选择10行。
    
    SQL> select avg(a.salary) from
      2  (select
      3  id,salary,rank() over (order by salary asc) as seq,rank() over (order by salary desc) as revseq,(select ceil(count(*)/2) from tb_coder1) as ceil
      4  from tb_coder2 order by salary) a
      5  where a.seq=a.ceil or a.revseq=a.ceil;
    
    AVG(A.SALARY)
    -------------
           9559.5

    --2020年4月11日--

    千夫诺诺,不如一士谔谔。 能正面指出你的不足的人,才是真正对你有帮助的人。

  • 相关阅读:
    Memcached通信协议
    quartz在集群环境下的最终解决方案
    在中间层 .NET 应用程序中通过授权管理器使用基于角色的安全
    微软MVC框架实战:开源的JS库Knockout
    EL表达式
    Hadoop安装配置
    Memcached安装
    Maven对不同的测试环境用不同的参数进行打包
    项目管理案例:赢与非输之别
    十年WEB技术发展历程
  • 原文地址:https://www.cnblogs.com/heyang78/p/12677633.html
Copyright © 2011-2022 走看看