[英]ROWNUMBER function in Oracle
小解釋:
我有一個名為passes
的表,它與2個表( services
(cod_serv)和atend
(通過))鏈接在一起。 可以為不同的服務復制通行證。
例如:如果我有3個服務,那么對於同一服務,我可以有3個通過nº01, 但沒有2個通過nº1(我在復合主鍵中定義了它)。
為了進行測試,我添加了102個通行證(所有情況都為“ F”且日期(今天)相同)。 然后,我為每個服務添加了34個通行證(我有3個服務)。
以下查詢顯示了schema
是如何定義的。
SELECT DISTINCT s.pass, s.data, cod_serv, situation, hour, min
FROM passes
JOIN atend a ON s.pass = a.pass;
PASS DATA COD_SERV S HOUR MIN
----- -------- --------- - ------- -------
04 26/03/16 2 F 12 24
04 26/03/16 1 F 13 27
13 26/03/16 1 F 14 26
18 26/03/16 3 F 14 27
18 26/03/16 2 F 14 28
15 26/03/16 1 F 14 29
10 26/03/16 3 F 14 30
... ... ... ... ... ...
然后,我想從特定日期獲取第100次( ROWNUMBER()
)通過(如下圖所示,其值為21),情況='F',按小時和分鍾排序。
第100行:
21 26/03/16 3 F 14 34
以下query
未返回任何內容,我不知道為什么。 順便說一句,在這種情況下,我有100多個通行證。
SELECT DISTINCT pass, data, cod_serv, situation FROM
(SELECT DISTINCT a.pass, s.data, cod_serv, situation,
ROW_NUMBER() OVER(PARTITION BY situation, hour, min
ORDER BY situation, hour, min) row
FROM passes s
JOIN atend a ON s.pass = a.pass
WHERE situation = 'F' AND
TRUNC(a.data) = TRUNC('some date'))
WHERE row = 100;
編輯:
我目前的查詢:
SELECT DISTINCT pass, cod_serv FROM
(SELECT DISTINCT s.pass, cod_serv,
ROW_NUMBER() OVER(PARTITION BY TRUNC(s.data)
ORDER BY a.hour, a.min) row
FROM passes s
JOIN atend a ON s.pass = a.pass
WHERE s.situation = 'F' AND
TRUNC(s.data) = TRUNC(SYSDATE))
WHERE row = 100;
在OVER
子句的PARTITION BY
和ORDER BY
中具有相同的字段幾乎沒有意義。
PARTITION BY
子句應列出定義從1開始對記錄進行計數的組的字段。
ORDER BY
子句定義該組中記錄的計數順序。
在您撰寫時:
我想從特定日期獲得第100次(
ROWNUMBER()
)傳遞,情況='F',按小時和分鍾排序
...您實際上是在說這些條款中需要寫的內容:
ROW_NUMBER() OVER(PARTITION BY data, situation ORDER BY hour, min)
因此,您的主要錯誤是將小時和分鍾放在PARTITION BY
子句中,一旦發現分鍾差,就使記錄計數從1開始,大多數記錄的編號為1。
編輯
似乎沒有選擇時,Oracle不會保留相同的row
號。 這可能是因為ORDER BY hour, min
不確定。 無論是什么原因,都可以通過選擇外部查詢中的row
來解決:
SELECT pass, row FROM ( ... etc ...) WHERE row = 100
如果只需要通過,則可以再次包裝該查詢:
SELECT pass FROM (
SELECT pass, row FROM ( ... etc ...) WHERE row = 100
)
這個怎么樣?
首先,在執行row_number()
之前,應用所有過濾器(因為您不想計算要過濾掉的行):
SELECT s.pass, s.data, cod_serv, s.situation, a.hour, a.min
FROM passes s
JOIN atend a ON s.pass = a.pass
WHERE s.situation = 'F'
AND TRUNC(s.data) = TRUNC(SYSDATE)
現在,將其包裝在外部查詢中,在其中應用row_number()
:
SELECT pass, data, cod_serv, situation, hour, min,
rowseq=row_number() over (order by hour, min)
FROM (
SELECT s.pass, s.data, cod_serv, s.situation, a.hour, a.min
FROM passes s
JOIN atend a ON s.pass = a.pass
WHERE s.situation = 'F'
AND TRUNC(s.data) = TRUNC(SYSDATE)
) t1
最后,將其包裝在外部查詢中,在其中將過濾器應用於“一百”條記錄:
SELECT pass, data, cod_serv, situation, hour, min
FROM (
SELECT pass, data, cod_serv, situation, hour, min,
rowseq=row_number() over (order by hour, min)
FROM (
SELECT s.pass, s.data, cod_serv, s.situation, a.hour, a.min
FROM passes s
JOIN atend a ON s.pass = a.pass
WHERE s.situation = 'F'
AND TRUNC(s.data) = TRUNC(SYSDATE)
) t1
WHERE rowseq = 100
最后,如果任何部分需要調整(不同的過濾器,聯接等),則可以自行運行這些內部查詢級別中的每一個,以檢查中間結果,以確保最終結果是所需的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.