簡體   English   中英

Oracle中的ROWNUMBER函數

[英]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 BYORDER 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM