hive开窗函数的案例-【sql练习】

数据:

语文,60

数学,70

语文,0

语文,10

语文,20

数学,50

语文,50

数学,40

英语,52

英语,51

英语,59

英语,97

英语,98

英语,100

数学,80

数学,90

英语,61

结果要求如下:

语文,0,1

语文,10,1

语文,20,1

数学,40,2

数学,50,2

语文,50,3

英语,51,4

英语,52,4

英语,59,4

语文,60,5

英语,61,6

数学,70,7

数学,80,7

数学,90,7

英语,97,8

英语,98,8

英语,100,8

思路:

观察数据可知,需要对数据进行升序排序,排序之后的数据当科目发生变化时,后面的数字就加1, 所以可以用开窗函数lag(col,n,default_val),得到前一行数据,再判断科目名称是否相等,如果相等就返回0,不相同就返回1。最后进行开窗的sum()。

具体操作:

1.按成绩升序排序

select

    subject,

    score,

    lag(subject) over(order by score asc) before_name

from stu_score;

结果如下:  

subject score   before_name

语文    0       NULL

语文    10      语文

语文    20      语文

数学    40      语文

数学    50      数学

语文    50      数学

英语    51      语文

英语    52      英语

英语    59      英语

语文    60      英语

英语    61      语文

数学    70      英语

数学    80      数学

数学    90      数学

英语    97      数学

英语    98      英语

英语    100     英语

2.判断当前科目名称与前一行名称是否相同,如果相等就返回0,不相同就返回1

select 

    subject,

    score,

    before_name,

    if( before_name=subject ,0,1) rn

    from(

        select

            subject,

            score,

            lag(subject) over(order by score asc) before_name

        from stu_score

    ) tmp;

结果如下:

subject score   before_name     rn

语文    0       NULL            1

语文    10      语文            0

语文    20      语文            0

数学    40      语文            1

数学    50      数学            0

语文    50      数学            1

英语    51      语文            1

英语    52      英语            0

英语    59      英语            0

语文    60      英语            1

英语    61      语文            1

数学    70      英语            1

数学    80      数学            0

数学    90      数学            0

英语    97      数学            1

英语    98      英语            0

英语    100     英语            0

3.使用sum(),开窗,进行累加

select 

    subject,

    score,

    before_name,

    sum(if( before_name=subject ,0,1)) over(order by score asc)rn

from(

    select

        subject,

        score,

        lag(subject) over(order by score asc) before_name

    from stu_score

) tmp;

结果如下:

subject score   before_name     rn

语文    0       NULL            1

语文    10      语文            1

语文    20      语文            1

数学    40      语文            2

数学    50      数学            3

语文    50      数学            3

英语    51      语文            4

英语    52      英语            4

英语    59      英语            4

语文    60      英语            5

英语    61      语文            6

数学    70      英语            7

数学    80      数学            7

数学    90      数学            7

英语    97      数学            8

英语    98      英语            8

英语    100     英语            8

问题:

数学    50      数学            3  应该为 数学    50      数学            2

原因:

开窗范围默认是:

 When ORDER BY is specified with missing WINDOW clause, the WINDOW specification defaults to RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.

此处RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,开窗范围为第一行到当前行,所以最开始的窗口里只有第一行数据,subject与前一行科目名称不相同,所以rn为1,sum()之后结果为1;窗口是慢慢累积的,所以接下来就是第一行和第二行,第二行科目名称和前一行科目名称相同,所以rn为0,sum=1+0=1,以此类推。

但range是根据值来开窗的,所以遇到两个成绩相同时,这两个都在一个窗口里,所以50这个值对应的sum=1+1+1=3

解决:

按照物理的行来开窗ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

4.最终结果

select 

    subject,

    score,

    before_name,

    sum(if( before_name=subject ,0,1)) over(order by score asc ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)rn

from(

    select

        subject,

        score,

        lag(subject) over(order by score asc) before_name

    from stu_score

) tmp;

结果如下:

subject score   before_name     rn

语文    0       NULL            1

语文    10      语文            1

语文    20      语文            1

数学    40      语文            2

数学    50      数学            2

语文    50      数学            3

英语    51      语文            4

英语    52      英语            4

英语    59      英语            4

语文    60      英语            5

英语    61      语文            6

数学    70      英语            7

数学    80      数学            7

数学    90      数学            7

英语    97      数学            8

英语    98      英语            8

英语    100     英语            8

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容