PostgreSQL添加了FETCH FIRST WITH TIES..。就像SQL Server中的前N名一样

2020-05-23 00:59:04

PostgreSQL13Beta1昨天发布了,你可以在这里阅读发行说明https://www.postgresql.org/about/news/2040/有一件事引起了我的注意,那就是发行说明中的这句话PostgreSQL13给编写查询带来了更多的便利,比如FETCH First with Ties,它会返回任何与最后一行匹配的附加行。我猜这与SQL Server中的领带TOP非常相似。我相信这至少从版本7开始就在SQL Server中出现了。我在过去20年中部署的代码中使用过它多少次?我相信我只使用过一次与领带一起使用。它确实有助于回答很棒的面试问题和SQL谜题(:-)所以让我们快速了解一下top with tie在SQL Server中是如何工作的。我们要做的第一件事是看看Books Online对top with tie的描述,它返回两行或更多行,在有限的结果集中并列为最后一位。必须将此参数与ORDER BY子句一起使用。WITH TIES可能会导致返回的行数多于表达式中指定的值。例如,如果表达式设置为5,但另外两行与行5中ORDER BY列的值匹配,则结果集将包含七行。您只能在SELECT语句中使用WITH TIES参数指定TOP子句,而且只有在您还指定了ORDER BY子句的情况下。捆绑记录的返回顺序是任意的。ORDER BY不影响此规则。

是时候开始编写一些代码来查看实际情况了首先创建这个学生表并插入一些数据CREATE TABLE#TopExample(GradeAverage int,Student varchar(100))INSERT#TopExample Values(99.00,&39;Plato&39;),(98,#39;苏格拉底),(95,#39;Digenes the Cynic&39;),(94,&39;Antisthenes';),(94,&39;Antisthenes';)。),(50,#39;丹尼斯#39;)。

正如你所看到的,我不是一个很好的学生:-(如果你像这样做一个常规的前4名查询,你会得到这些结果,因为你可以看到我们缺少了另一个成绩为94的学生,这是Antisthenes现在通过添加纽带到查询很容易修复的,你会得到这些结果,正如你可以看到的,你现在有5行,包括平均成绩为94的两行另一种方法是通过使用Dense_RANK来做同样的事情。该查询看起来是这样的;使用c As(SELECT Dense_RANK()over(ORDER BY GradeAverage DESC))作为DENS、GradeAverage、Students from#TopExample)SELECT GradeAverage、Students from c,其中DENS<;=4 ORDER BY GradeAverage DESC。

您将再次获得相同的结果,您现在有5行,并且还包括平均成绩为94的两行。

使用DENSE_RANK的代码稍多一些,但如果考虑到可移植性,您可能会更好地选择发布有关您永远不会使用的功能的帖子:-)如果您想一次运行所有查询,这里是所有代码CREATE TABLE#TopExample(GradeAverage int,Students varchar(100))INSERT#TopExample Values(99.00,';Plato';),(98.00,';苏格拉底';),(95.00。),(94.00,#39;Antisthenes&39;),(94.00,&39;Demetrius&39;),(50.00,&39;Denis&39;)选择前4个年级平均,学生从#顶部排序按年级排序示例按年级排序平均,学生从#顶部选择并列平均年级,学生从#顶部排序示例按年级排序平均,带c(SELECT Dense_RANK()。=4 ORDER BY GRADE Average DESC DROP TABLE#TopExample