2016-11-12 89 views
0

我有一個列C1,C2,C3,C4,C5,C6和計數表。我必須按照C1,C2,C3,C4,C5的順序排列記錄。對於第一條記錄,計數將爲0,那麼如果下一行的C1,C2,C3,C4,C5的值與前一行相同,那麼我必須通過加+1來更新計數列。所以這就是我期待: 表:根據以前的記錄更新列

C1 C2 C3 C4 C5 C6  Count 
------------------------------------------- 
1 A  X  X1 AA 123  0 
1 A  X  X1 AA 121  1 
1 A  X  X1 AA 118  2 
1 A  X  X1 AA 117  3 
2 B  X  X2 AA 234  0 
8 A  Y  X3 AA 298  0 
8 A  Y  X3 AA 800  1 

我使用Oracle數據庫。我用Cursor with Order by編寫了一個PL SQL塊,然後在BULK COLLECT中使用該遊標,並與前一記錄進行迭代。但是,Count列更新爲意外記錄並花費比預期多得多的時間,表中有大約40萬條記錄。我無法在這裏鍵入我的代碼,因爲實際代碼在客戶端計算機中。任何幫助,高度讚賞。可以使用PL/SQL或簡單SQL。 DB是Oracle。

+0

爲什麼需要用光標和BULK COLLECT編寫一個PL/SQL塊並遍歷每一行等?學習在普通SQL中這樣做的正確方法要容易得多,而且效率要高得多 - 而且學習適當的SQL比學習PL/SQL要花費更少的時間。那麼:爲什麼你需要在表中排序「計數」?在視圖中或在查詢中生成報告是有意義的;將它存放在桌子上只會導致未來的問題。如果將來某行被刪除,或者C3從Y更正爲X,該怎麼辦?現在你必須重新計算整個列!餿主意。 – mathguy

回答

1

我相信你想row_number()

select t.*, 
     (row_number() over (partition by c1, c2, c3, c4, c5 order by c6) - 1 
     ) as "Count" 
from t; 

您可以使用merge把這個在update聲明。或者,如果你真的想要一個update

update t 
    set count = (select count(*) 
       from t t2 
       where t2.col1 = t.col1 and t2.col2 = t.col2 and t2.col3 = t.col3 and 
         t2.col4 = t.col4 and t.col5 = t2.col5 and 
         t2.col6 < t.col6 
       ); 
+0

謝謝。使用你的查詢我能夠解決這個問題。 – Sid

+0

按col6排序沒有韻律或理由,不知道您是否注意到。在(A,X)的情況下,OP顯示按col6遞減的DESC排序的「計數」,但在(A,Y)的情況下按順序6顯示ASC排序的「計數」遞增。可能不值得進一步研究,因爲整個任務確實沒有意義。 – mathguy

0

與戈登·利諾夫提供線索的幫助下,我能解決這個問題。但是,我創建了一個新表而不是更新以避免性能問題。以下是查詢:

CREATE TABLE TAB2 AS 
SELECT T1.C1, T1.C2, T1.C3, T1.C4, T1.C5, T1.C6, T1.REC_COUNT 
(select t.*, 
     (row_number() over (partition by c1, c2, c3, c4, c5 order by c1, c2, c3, c4, c5) - 1 
     ) as rec_count 
from tab1 T) T1; 
+0

按照你所劃分的那些列(或者它們的一個子集)排列的順序會導致隨機排序 - 這似乎是你想要的;在固定的c1到c5範圍內,你所提供的順序沒有明顯的邏輯。 (你在那裏的順序是「random」的原因是它在每個分區中,其中c1到c5對於分區中的所有行是固定的。)通過省略「order by c1」得到完全相同的(隨機)結果,...,c5「全部來自row_number()參數。只需保留一部分分區。 – mathguy

相關問題