實現select top 1 * from tablename
Oracle 中的 ROW_NUMBER() OVER() 分析函數的用法
ROW_NUMBER() OVER(partition by col1 order by col2) 表示根據col1分組,在分組內部根據col2排序,而此函數計算的值就表示每組內部排序后的順序編號(組內是連續且唯一的)。
舉例:
SQL> DESC T1;
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER
NAME VARCHAR2(10)
DATE1 DATE
SQL> SELECT * FROM T1;
ID NAME DATE1
---------- ------------------------------ ------------------
101 aaa 09-SEP-13
101 bbb 10-SEP-13
101 ccc 11-SEP-13
102 ddd 08-SEP-13
102 eee 11-SEP-13
SQL> SELECT ID,NAME,DATE1,ROW_NUMBER() OVER(partition by ID order by DATE1 desc) as RN FROM T1;
ID NAME DATE1 RN
---------- ------------------------------ ------------------ ----------
101 ccc 11-SEP-13 1
101 bbb 10-SEP-13 2
101 aaa 09-SEP-13 3
102 eee 11-SEP-13 1
102 ddd 08-SEP-13 2
把上面語句作為一個子表語句,嵌入到另一條語句中:
SQL> SELECT ID,NAME,DATE1 FROM (SELECT ID,NAME,DATE1,ROW_NUMBER() OVER(partition by ID order by DATE1 desc) as RN FROM T1)T WHERE T.RN=1;
ID NAME DATE1
---------- ------------------------------ ------------------
101 ccc 11-SEP-13
102 eee 11-SEP-13
簡單介紹:在Oracle中使用row_number() over()函數,對查詢的結果進行分組,並支持分組后的排序功能,這是我使用之后的簡單理解。
場景1:在面試過程中經常遇到的一個問題,把一個班中每一科成績最高的人查找出來。
思路:查詢出一個班所有科目的成績,使用row_number() over()按照科目分組並按成績降序排列。
表數據如圖所示:
sql語句:
1
|
SELECT
T.
NAME
,T.SUBJECT,T.SCORE ,row_number()OVER(PARTITION
BY
T.SUBJECT
ORDER
BY
T.SCORE
DESC
) SEQ
FROM
JAVA_SCORE T;排序結果:
|
場景2:刪除成績表中科目重復的數據,僅保留分數最高的一條。
思路:row_number()OVER(PARTITION By 字段1,字段2 ORDER BY 排序字段)中的PARTITION By作用於分組函數group一致,但是row_number()OVER()的執行是在where 、group by、 order by 之后執行的。也就是對結果一個分組排序。
SQL:
1
2
3
4
5
|
DELETE
FROM
JAVA_SCORE
where
id
in
(
--執行刪除操作
SELECT
ID
FROM
(
SELECT
T.ID, T.
NAME
,T.SUBJECT,T.SCORE ,row_number()OVER(PARTITION
BY
T.SUBJECT
ORDER
BY
T.SCORE
DESC
) SEQ
FROM
JAVA_SCORE T
--按照科目分組,並根據分數排序
) T
WHERE
T.SEQ > 1
--篩選不是第一名的數據
)
|