2017-06-11 66 views
0

我有一個查詢,它返回每個gid最常見的值。代碼如下:如何在PostgreSQL中沒有公共值時選擇零點?

select distinct on(gid) gid, max_height 
from (
select gid, max_height, count(id) as freq 
from my_table 
group by 1, 2 
) s 
order by gid, freq desc, max_height desc 

對於下面的示例數據:

gid id max_height 
3 1 19.3 
3 2 19.3 
3 3 20.3 
3 4 20.3 
3 5 19.3 
3 6 19.3 
3 7 21.4 
3 8 21.4 
3 9 21.4 
3 10 21.4 
3 11 21.4 
3 12 21.4 
22 1 23.1 
22 2 23.1 
22 3 23.1 
22 4 23.1 
22 5 23.1 
22 6 23.1 
22 7 22.1 
22 8 22.1 
22 9 22.1 
22 10 22.1 
22 11 22.1 
22 12 22.1 
29 1 24.1 
29 2 22.2 
29 3 25.3 
29 4 15.4 
29 5 17.2 
29 6 18.9 
29 7 2.5 
29 8 3.5 
29 9 25.1 
29 10 27.1 
29 11 5.5 
29 12 6.5 

每個GID是獨特的,它包含ID和MAX_HEIGHT的12個值。我需要修改上面的代碼,以便在任何gid沒有最常見的值(模式)時它應該返回0.0。基於此,期望的輸出可能是:

gid max_height 
3  21.4 
22  23.1 
29  0.0 

任何人都可以提供一些指針來獲得我想要的輸出嗎?

回答

3

freq在選擇列表中添加一個條件:

select distinct on(gid) 
    gid, case when freq > 1 then max_height else 0.0 end as max_height 
from (
    select gid, max_height, count(id) as freq 
    from my_table 
    group by 1, 2 
    ) s 
order by gid, freq desc, max_height desc; 

gid | max_height 
-----+------------ 
    3 |  21.4 
    22 |  23.1 
    29 |  0.0 
(3 rows)  
2

您似乎誤解了「最常見的價值」。 29有一個最常見的價值 - 事實上其中很多。這被稱爲模式。

如果你想知道,如果模式不是唯一的,那麼這裏是一個Postgres'y方式:

select gid, 
     (case when mode() over (partition by gid order by max_height desc) <> 
        mode() over (partition by gid order by max_height asc) 
      then 0.0 
      else mode() over (partition by gid order by max_height desc) 
     end) as most_freq 
from my_table 
group by gid; 

這將檢查模式的獨特性,使用的是Postgres的內置功能。

+0

ERROR:功能模式()不存在。我在嘗試測試代碼時遇到此錯誤。 –

+0

https://www.postgresql.org/docs/9.5/static/functions-aggregate.html –