如果PostgreSQL中没有常用值,如何选择零?

时间:2017-06-11 17:48:26

标签: sql postgresql

我有一个查询,它返回每个gid的最常见值。代码如下:

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都是唯一的,它包含12个ID和max_height值。我需要修改上面的代码,以便在没有任何gid的最常见值(模式)时返回0.0。基于此,期望的输出可以是:

gid    max_height
3      21.4
22     23.1
29     0.0

任何人都可以提供一些指示来获得我想要的输出吗?

2 个答案:

答案 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)    

答案 1 :(得分:2)

你似乎误解了“最常见的价值”。 29有一个最常见的价值 - 事实上其中很多。这称为模式。

如果你想知道模式是不是唯一的,那么这是Postgres的一种方式:

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的内置函数检查模式的唯一性。