2017-07-02 63 views
2

我試圖對跨兩列具有保存值的行進行分組,並根據第三列對結果進行排序/排序。配置單元 - 根據某些列選擇唯一行

結果應包含所有其他列。

對於表:

with sample as (
select 'A' as c1, 'B' as c2, '22:00' as c3, 'Da' as c4 
union all 
select 'A' as c1, 'B' as c2, '23:00' as c3, 'Db' as c4 
union all 
select 'A' as c1, 'B' as c2, '09:00' as c3, 'Dc' as c4 
    union all 
select 'A' as c1, 'C' as c2, '22:00' as c3, 'Dd' as c4 
    union all 
select 'B' as c1, 'C' as c2, '09:00' as c3, 'De' as c4 
) 

分組或過濾通過柱C1C2由時間上C3排名,輸出將是:

row_number() over (partition by c1, c2 order by c3) as rnk 

| c1, c2, c3, c4, rnk| 
----------------------- 
| A | B |09:00| Dc| 1 | 
| A | B |22:00| Da| 2 | 
| A | B |23:00| Db| 3 | 
| A | C |22:00| Dd| 1 | 
| B | C |09:00| De| 1 | 

所有其他像c4,c5 ..這樣的列應該保留,但對組標準或等級沒有任何影響。

一相信,隨着分區上C1C2和秩序的窗口功能被C3可以工作,但不知道這是否是在非常大的表的情況下,最好的辦法,並通過多個列中的必要組。

最終輸出將是排名爲1(頂部)的UNIQUE行。這些列應該與樣本表格(無級別)完全相同。

Select * from tableX where rnk = 1會做的工作,但保持專業'rnk'。 我想避免寫中的所有列,不包括的rnk。

| c1, c2, c3, c4 | 
------------------- 
| A | B |09:00| Dc| 
| A | C |22:00| Dd| 
| B | C |09:00| De| 

*編輯,加決賽桌

+0

'rnk'作爲'row_number'的別名不是一個好的選擇,因爲還有一個'rank'窗口函數,具有不同的含義 –

回答

2
select inline(array(rec)) 

from (select struct(*) as rec 

       ,row_number() over 
       (
        partition by c1,c2 
        order by  c3 
       ) as rn 

     from sample t 
     ) t 

where rn = 1 
; 

+------+------+-------+------+ 
| col1 | col2 | col3 | col4 | 
+------+------+-------+------+ 
| A | B | 09:00 | Dc | 
| A | C | 22:00 | Dd | 
| B | C | 09:00 | De | 
+------+------+-------+------+ 

附: 請注意,由於使用struct

+0

這很有效,謝謝 –

0

我覺得你只是想row_number()

select t.*, 
     row_number() over (partition by c1, c2 order by c3) as rnk 
from sample t; 

這個問題似乎因爲我回答它已經改變了 - 一個相當不禮貌的行爲發生。如果你想排名靠前列,然後使用子查詢:

select t.* 
from (select t.*, 
      row_number() over (partition by c1, c2 order by c3) as rnk 
     from sample t 
    ) t 
where rnk = 1; 

這將返回一行數據C1/C2的每個組合。如果您想要關聯所有行,請使用rank()而不是row_number()

+0

是的,抱歉。我編輯了這個問題。你做的第一部分我擁有它,我的問題是如何過濾掉重複。並且在結果中不顯示列「rnk」。你發佈的內容確實顯示** rnk **列。 –

+0

@RD。 。 。只需在外部查詢中選擇您想要的列。 'SELECT *'是回答問題的方便方式,但可能並不完全符合您的要求。 –

+0

是的,我想避免需要命名所有列。 ** ALL **,**除了'rnk'。 'select *'不是我所需要的 –