我有一个由其他人编写的SQL查询,我想弄清楚它是做什么的。有人能解释一下Partition By
和Row_Number
关键字在这里做什么,并给予一个简单的例子,以及为什么要使用它吗?
按以下方式划分的示例:
(SELECT cdt.*,
ROW_NUMBER ()
OVER (PARTITION BY cdt.country_code, cdt.account, cdt.currency
ORDER BY cdt.country_code, cdt.account, cdt.currency)
seq_no
FROM CUSTOMER_DETAILS cdt);
4条答案
按热度按时间ippsafx71#
PARTITION BY
隔离集合,这使您能够独立地处理相关集合(ROW_NUMBER()、COUNT()、SUM()等)。In your query, the related set comprised of rows with similar cdt.country_code, cdt.account, cdt.currency. When you partition on those columns and you apply ROW_NUMBER on them. Those other columns on those combination/set will receive sequential number from ROW_NUMBER
但是这个查询很有趣,如果你用一些唯一的数据进行分区,并且你在它上面放了一个row_number,它只会产生相同的数字。这就像你在一个保证是唯一的分区上做了一个ORDER BY。
newid()
产生GUID,那么这个表达式应该有什么作用呢?...对,所有分区的行(没有分区,每行都在自己的行中分区)的row_numbers都设置为1
基本上,您应该对非唯一列进行分区。OVER上的ORDER BY需要PARTITION BY具有非唯一组合,否则所有row_numbers将变为1
举个例子,这是你的数据:
那么这与您的查询类似:
这将产生什么结果?
您看到HI HO的组合了吗?前三行具有唯一的组合,因此它们被设置为1,B行具有相同的W,因此具有不同的ROW_NUMBERS,HI C行也是如此。
那么,为什么需要
ORDER BY
呢?如果以前的开发人员只想在类似的数据上放置一个row_number(例如HI B,所有数据都是B-W,B-W),他可以这样做:但是遗憾的是,Oracle(和Sql Server)不允许没有
ORDER BY
的分区;而在Postgresql中,PARTITION上的ORDER BY
是可选的:http://www.sqlfiddle.com/#!1/27821/1你的分区上的
ORDER BY
看起来有点多余,不是因为以前的开发人员的错误,有些数据库不允许PARTITION
没有ORDER BY
,他可能无法找到一个很好的候选列排序。如果PARTITION BY列和ORDER BY列相同,只需删除ORDER BY,但由于有些数据库不允许,您可以这样做:你找不到一个好的列来排序类似的数据?你可以随机排序,分区数据有相同的值。你可以使用GUID作为例子(你使用
newid()
for SQL Server)。所以这与以前的开发人员所做的输出相同,不幸的是,一些数据库不允许PARTITION
没有ORDER BY
虽然真的,它逃避我,我找不到一个很好的理由把一个数字在相同的组合(B-W,B-W在上面的例子)。它给人的印象数据库有冗余数据。不知何故提醒我这一点:How to get one unique record from the same list of records from table? No Unique constraint in the table
它真的看起来很神秘,看到一个分区与相同的列组合与顺序,不能轻易推断代码的意图。
实时测试:http://www.sqlfiddle.com/#! 3/27821/6
但是正如dbaseman也注意到的,在同一列上进行分区和排序是没有用的。
你有这样一组数据:
然后你被嗨,嗬;然后你ORDER BY hi,ho.给类似的数据编号是没有意义的:-)http://www.sqlfiddle.com/#! 3/29ab8/3
输出:
看到了吗?为什么需要把行号放在同一个组合上?你会在三个A,X上,两个B,Y上,两个C,Z上分析什么?:-)
你只需要在非唯一列上使用PARTITION,然后在非唯一列的 * unique *-ing列上排序。下面的例子会更清楚:
PARTITION BY hi
对非唯一列进行操作,然后对每个分区列按其唯一列(ho)ORDER BY ho
进行排序输出:
这个数据集更有意义
实时测试:http://www.sqlfiddle.com/#! 3/d0b44/1
这类似于PARTITION BY和ORDER BY上具有相同列的查询:
这是输出:
看到了吗,没道理?
实时测试:http://www.sqlfiddle.com/#! 3/d0b44/3
最后,这可能是正确的查询:
1aaf6o9v2#
我经常使用row_number()作为一种快速的方法来丢弃select语句中的重复记录。只需添加一个where子句。类似于...
k4ymrczo3#
它选择每个国家代码、账户和货币的行号,因此,国家代码为“US”、账户为“XYZ”、货币为“$USD”的行将分别获得从1到n分配的行号;这同样适用于结果集中那些列的每一个其它组合。
这个查询很有趣,因为order by子句什么都不做,每个分区中的所有行都有相同的国家代码、帐户和货币,所以没有按这些列排序的点,因此在这个特定查询中分配的最终行号是不可预测的。
希望能有所帮助...
fnatzsnv4#
我知道这是一个旧的线程,但是PARTITION等同于GROUP BY而不是ORDER BY。在这个函数中ORDER BY是... ORDER BY。它只是一种通过添加序列号从冗余中创建唯一性的方法。或者,您可以在引用函数的别名列时通过WHERE子句消除其他冗余记录。但是,在这方面,SELECT语句中的DISTINCT可能会完成同样的任务。