如何在一个值的数量大于另一个值的 postgresql 行中进行选择?

How to choose in postgresql rows where amount of one value is bigger than another?

如何在一个值的数量大于另一个值的 postgresql 行中进行选择? 例如,我只需要选择那些推荐的更大的:

换句话说:

create table t(id bigint, place text, opinion text);
insert into t values
    (1, 'mnt', 'yes'),
    (2, 'mnt', 'no'),
    (3, 'mnt', 'no'),
    (4, 'cod', 'yes'),
    (5, 'cod', 'yes'),
    (6, 'cod', 'yes'),
    (7, 'qrw', 'yes'),
    (8, 'qrw', 'no'),
    (9, 'caf', 'no'),
    (10, 'mnt', 'yes');

我试着按地点、意见分组统计

如果您正在寻找推荐大于不推荐的地方,您可以使用聚合:

select place
from t
group by place
having count(*) filter (where opinion = 'recommended') > count(*) filter (where opinion = 'not recommended');

您也可以更简单地表达为:

select place
from t
where opinion in ('recommended', 'not recommended')
group by place
having avg( (opinion = 'recommended)::int ) > 0.5;

我认为您想要“推荐”意见多于“不推荐”意见的地方。如果是这样,您可以使用带有 having 子句的聚合和过滤器:

select place
from mytable
group by place
having count(*) filter(where opinion = 'recommended') 
     > count(*) filter(where opinion = 'not recommended')

如果你想要这些行的详细信息,你可以使用window函数:

select *
from (
    select t.*,
        count(*) filter(where opinion = 'recommended'    ) over(partition by place) as cnt_recommended,
        count(*) filter(where opinion = 'not recommended') over(partition by place) as cnt_not_recommended
    from mytable t
) t
where cnt_recommended > cnt_not_recommended

另一组 BY/HAVING 备选方案。

select place
from tablename
group by place
having sum(case when opinion = 'recommended' then 1
                when opinion = 'not recommended' then -1
           end) > 0

编辑: @Abelisto 建议这样做,从推荐到不推荐排序:

select place
from tablename
group by place
order by sum(case when opinion = 'recommended' then 1
                  when opinion = 'not recommended' then -1
             end) desc

编辑 2

select
    place,
    sum(
        case
            when opinion = 'recommended' then 1
            when opinion = 'not recommended' then -1
            else 0
        end) as rate
from tablename
group by place
order by rate desc