2016-03-26 33 views
0

一點解釋:ROWNUMBER功能

我有一個表叫passes和它與2個表(services(cod_serv)和atend(通過))鏈接。通票可以複製用於不同的服務。例如:如果我有3項服務,我可以有3次通行證,01,但是對於相同的服務(我在我的複合主鍵中定義它),不是2次通過1次。

對於測試,我添加了102個通行證(所有的情況=「F」和相同的日期(今天))。然後,我添加了每個服務的通行證(我有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 
...  ...  ...   ... ...   ... 

然後,我想從一個特定的日期與時間和最小的情況=「F」排序得到的第100(ROWNUMBER())通(因爲它顯示下面是21)。

行號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; 
+0

你想'(按小時,分鐘按數據順序分區)' –

+0

和'情況'? – developer033

+0

無論如何,所有行都會具有相同的值(因爲'situacao ='F'),所以不需要將它包含在窗口定義或訂單中。 –

回答

0

具有PARTITION BYORDER BY相同的字段在OVER條款意義不大。

PARTITION BY條款應列出定義中,你開始從1

計數記錄的ORDER BY節定義記錄被該組中計算的順序組的字段。

當你寫:

I want to get the 100th (ROWNUMBER()) pass from a specific date with the situation = 'F' ordering by hour and min

...你竟然說用言語什麼需要把這些條款:

ROW_NUMBER() OVER(PARTITION BY data, situation ORDER BY hour, min) 

所以,你的主要錯誤是把小時PARTITION BY條款中,一旦發現一分鐘差異,使得記錄從1開始計數,給出您的大部分記錄數字1.

編輯

看來,當沒有選擇Oracle不保留相同row數量。這可能是因爲ORDER BY hour, min不確定。再次

SELECT pass, row FROM (... etc ...) WHERE row = 100 

如果你只需要通,你可以用該查詢:

SELECT pass FROM (
    SELECT pass, row FROM (... etc ...) WHERE row = 100 
) 
+0

感謝您的支持,但不幸的是,這並不奏效。但是我認爲這不是首先工作的,因爲正如我在上次編輯中提到的那樣,即使使用「DISTINCT」,內部'select'也會在'passes'表中返回3倍的行數。所以我必須先解決它 – developer033

+0

看看'SELECT數據的輸出,count(*)FROM傳遞WHERE情況='F'GROUP BY數據HAVING count(*)> 99'來查看有多少個case你有100多行。 – trincot

+0

我測試了它。 Count = 102(這是正確的,我將所有情況更新爲'F')。 – developer033

0

這個怎麼樣不管是什麼原因,它可以通過在外部查詢選擇row解決?

首先,做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 

最後,如果有任何部分需要調整(不同的過濾器,連接等),您可以自行運行這些級別的內部查詢以檢查您的中間結果,以確保您的結果最終是您想要的結果。

+0

謝謝你的回答,但它給了我錯誤:'ORA-00923:FROM keyword not found where expected' – developer033