开窗函数 SQL Server中的开窗函数是什么
大家好,关于开窗函数很多朋友都还不太明白,今天小编就来为大家分享关于SQL Server中的开窗函数是什么的知识,希望对各位有所帮助!
case when能和开窗函数一起用吗
CASE WHEN wst.score- 60< 0 THEN---当wst.score<60的时候执行开窗函数RANK() OVER
RANK() OVER(PARTITION BY当wst.score<60的时候,如果wst.score>=60直为null,否则的话当作'A',--〉最终结果是按照wst.score<60(也就是null)和'A'分组
CASE WHEN wst.score- 60>= 0 THEN NULL
ELSE'A' END ORDER BY wst.score DESC
)
END
整个就是
1)如果wst.score<60
1.1按照<60('A').>=60(NULL)分组,注意,此时分组的是A和null
1.2按照A和NULL分组后按照wst.score组内降序排列
所以说你那个SQL语句性能很不好,可以优化的。你可以给个例子和你想要得结果,我可以帮你看看能否改进。
另外,你最外层那个CASE没有else,程序很不健壮哦。。。
为什么我们要使用开窗函数
什么时候会用到开窗函数呢?下面介绍使用场景:
表test1数据如下:
现在我们有需求:查出它们每个年级(class)的平均分数,预期结果格式如下:
我们可以看到,根据年级class求avg()聚合后的数据会变少一条,但是,我们既要显示聚合前的数据又要显示聚合后的数据,这个时候就要使用开窗函数。
测试:
查询数据:
返回结果:
出现的两个问题:
1.如果我们在partition by class加一个order by id会出现什么问题
返回结果:
可以看到class为1的两条avg值不一致,这是因为order by id是来一条数据处理一条,所以第一条class为1的数据来的只能是99/1=99。
我们可能会这样想,先查询出数据放到一张临时表,然后在开窗,根据class分区,再根据id排序,可是结果并不是根据id全局有序的
返回结果:
因为它是按照分区排序的,所以是分区内有序。
另外,我们和group by分组做个对比
原始数据如下
我们可能会想,为什么同样在这里使用了聚合函数sum(),数据条数变少了,我们为什么没有开窗呢?
这里使用group by进行了分组,根据id和时间进行分组。
那我们想是否上面也可以使用group by而不使用开窗呢?
如下sql是否可以呢?
返回结果:
答案是不可以。因为我们select了多个字段,所以我们要根据多个字段来分组,class相同再根据id分组,id相同再根据score分组。导致我们不能仅仅根据class分组,也就导致最后分组出来的数据除了class、id、score都相同的两条数据能够聚合,否则都是单条数据自己聚合。
所以我们要使用group by就只能选取单个字段
返回结果
SQL Server中的开窗函数是什么
开窗函数(OVER子句)用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合),它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行
中同时返回基础行的列和聚合列。举例来说,如果要得到一个年级所有班级所有学生的平均
分,按照传统的写法,肯定是通过AVG聚合函数来实现求平均分。由于聚合函数是以GROUP BY查询作为操作的上下文对一组值进行聚合,GROUP BY操作对数据进行分组后,查询
为每个组只返回一行数据,因此,我们不能同时返回基础列(班级,学生等列),而只能得
到聚合列。
开窗函数会导致取数更慢吗
不会。在计算机函数中,开窗函数并不会导致计算机取数值结果更慢,反而会更快。开窗函数用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合),它对一组值进行操作,不需要使用GROUPBY子句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列。
文章到此结束,希望我们对于开窗函数和SQL Server中的开窗函数是什么的问题能够给您带来一些启发和解决方案。如果您需要更多信息或者有其他问题,请随时联系我们。