partition by關鍵字是分析性函數的一部分,它和聚合函數不同的地方在於它能傳回一個分組中的多筆記錄,而聚合函數一般只有一筆反映統計值的記錄,partition by用來將結果集分組,如果沒有指定那麼它將整個結果集作為一個分組。
今天群組裡看到一個問題,在這裡概述下:查詢出不同分類下的最新記錄。一看這不是很簡單的麼,要分類那就用Group By;要最新記錄就用Order By唄。然後在自己的表中試著做出來:
相關學習推薦:mysql視頻教程
首先呢我把表中的數據按照提交時間倒序出來:
「corp_name」就是分類的GUID(請原諒我命名的隨意性)。 OK, 這裡按照最開始的想法加上Group By來看一下顯示效果:
呃,嗯。這尼瑪和想像中的結果不一樣啊,看來寫程式碼還是要理性分析問題,意念是無法控制結果滴!
既然要求是不同分類的數據,除了使用Group By之外,還有別的函數能用嗎?度娘了一下結果還真有,over(partition by )函數,那麼它和平時用的Group By有什麼差別呢? Group By除了對結果進行單純的分組之外呢,一般都和聚合函數一起使用,Partition By也具有分組功能,屬於Oracle的分析函數,在這裡就不詳細的不啦不啦不啦了。
看程式碼:
over(partition by corp_name order by submit_time desc ) as t 。就是按照corp_name分類並按時間倒序出來,"t" 這裡一列呢就是不同corp_name類出現的次數,需求是只查詢出不同分類的最新提交數據,那麼我們只需要針對"t"再進行一次篩選即可:
好啦,結果已經出來,不求各位看官喜歡,但求看在我頭像中的胸器望點個贊, 好人一生平安哦! ! !
ps:SQL Server資料庫partition by 與ROW_NUMBER()函數使用詳解
關於SQL的partition by 欄位的一些用法心得
先看範例:
if object_id('TESTDB') is not null drop table TESTDB create table TESTDB(A varchar(8), B varchar(8)) insert into TESTDB select 'A1', 'B1' union all select 'A1', 'B2' union all select 'A1', 'B3' union all select 'A2', 'B4' union all select 'A2', 'B5' union all select 'A2', 'B6' union all select 'A3', 'B7' union all select 'A3', 'B3' union all select 'A3', 'B4'
-- 所有的資訊
SELECT * FROM TESTDB A B ------- A1 B1 A1 B2 A1 B3 A2 B4 A2 B5 A2 B6 A3 B7 A3 B3 A3 B4
-- 使用PARTITION BY 函數後
SELECT *,ROW_NUMBER() OVER(PARTITION BY A ORDER BY A DESC) NUM FROM TESTDB A B NUM ------------- A1 B1 1 A1 B2 2 A1 B3 3 A2 B4 1 A2 B5 2 A2 B6 3 A3 B7 1 A3 B3 2 A3 B4 3
可以看到結果中多出一列NUM 這個NUM就是說明了相同行的個數,例如A1有3個,他就給每個A1標上是第幾個。
-- 只使用ROW_NUMBER() OVER的結果
SELECT *,ROW_NUMBER() OVER(ORDER BY A DESC)NUM FROM TESTDB A B NUM ------------------------ A3 B7 1 A3 B3 2 A3 B4 3 A2 B4 4 A2 B5 5 A2 B6 6 A1 B1 7 A1 B2 8 A1 B3 9
可以看到它只是單純標示了行號。
-- 深入一點應用
SELECT A = CASE WHEN NUM = 1 THEN A ELSE '' END,B FROM (SELECT A,NUM = ROW_NUMBER() OVER(PARTITION BY A ORDER BY A DESC) FROM TESTDB) T A B --------- A1 B1 B2 B3 A2 B4 B5 B6 A3 B7 B3 B4
接下來我們就透過幾個實例來一一介紹ROW_NUMBER()函數的使用。
實例如下:
1.使用row_number()函數進行編號,如
select email,customerID, ROW_NUMBER() over(order by psd) as rows from QT_Customer
原理:先按psd進行排序,排序完後,將每個資料編號。
2.在訂單中按價格的升序進行排序,並給每筆記錄進行排序代碼如下:
select DID,customerID,totalPrice,ROW_NUMBER() over(order by totalPrice) as rows from OP_Order
3.統計出每一個各戶的所有訂單並依每位顧客下的訂單的金額升序排序,同時給予每位顧客的訂單編號。這樣就知道每個客戶下幾單了。
如圖:
程式碼如下:
select ROW_NUMBER() over(partition by customerID order by totalPrice) as rows,customerID,totalPrice, DID from OP_Order
4.統計每個客戶最近下的訂單是第幾次下的訂單。
程式碼如下:
with tabs as ( select ROW_NUMBER() over(partition by customerID order by totalPrice) as rows,customerID,totalPrice, DID from OP_Order ) select MAX(rows) as '下单次数',customerID from tabs group by customerID
#5.統計每個客戶所有的訂單中購買的金額最小,而且並統計改訂單中,客戶是第幾次購買的。
如图:
上图:rows表示客户是第几次购买。
思路:利用临时表来执行这一操作。
1.先按客户进行分组,然后按客户的下单的时间进行排序,并进行编号。
2.然后利用子查询查找出每一个客户购买时的最小价格。
3.根据查找出每一个客户的最小价格来查找相应的记录。
代码如下:
with tabs as ( select ROW_NUMBER() over(partition by customerID order by insDT) as rows,customerID,totalPrice, DID from OP_Order ) select * from tabs where totalPrice in ( select MIN(totalPrice)from tabs group by customerID )
6.筛选出客户第一次下的订单。
思路。利用rows=1来查询客户第一次下的订单记录。
代码如下:
with tabs as ( select ROW_NUMBER() over(partition by customerID order by insDT) as rows,* from OP_Order ) select * from tabs where rows = 1 select * from OP_Order
7.rows_number()可用于分页
思路:先把所有的产品筛选出来,然后对这些产品进行编号。然后在where子句中进行过滤。
8.注意:在使用over等开窗函数时,over里头的分组及排序的执行晚于“where,group by,order by”的执行。
如下代码:
select ROW_NUMBER() over(partition by customerID order by insDT) as rows, customerID,totalPrice, DID from OP_Order where insDT>'2011-07-22'
以上代码是先执行where子句,执行完后,再给每一条记录进行编号。
以上是詳解SQLServer中Partition By及row_number函數的使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!