首页 > 解决方案 > 在 postgresql 中使用 group by 和 order

问题描述

询问:

select "fightEventId", fe."from" , f.status
from 
    location_time_slot lts 
inner join
    fight_events fe on lts."fightEventId" = fe.id
inner join
    fights f on lts.id = f."slotId"
where
    f.status = 'CONFIRMED'
    and true 
    and (
        now() at time zone 'utc' >= fe."from" and now() at time zone 'utc' <= fe."to" 
    )
    or true and now() at time zone 'utc' <= fe."to" 
    or false and now() at time zone 'utc' > fe."to"
order by fe."from" 
limit 100
offset 0;

它产生了这个:

fightEventId|from               |status   |
------------+-------------------+---------+
           2|2021-07-02 15:00:00|CONFIRMED|
           2|2021-07-02 15:00:00|CONFIRMED|
           2|2021-07-02 15:00:00|CONFIRMED|
           2|2021-07-02 15:00:00|CONFIRMED|
          17|2021-07-03 15:00:00|CONFIRMED|
          17|2021-07-03 15:00:00|CONFIRMED|
           1|2021-07-03 15:00:00|CONFIRMED|
           1|2021-07-03 15:00:00|CONFIRMED|
           1|2021-07-03 15:00:00|CONFIRMED|
           1|2021-07-03 15:00:00|CONFIRMED|
           1|2021-07-03 15:00:00|CONFIRMED|
           1|2021-07-03 15:00:00|CONFIRMED|
           1|2021-07-03 15:00:00|CONFIRMED|
           1|2021-07-03 15:00:00|CONFIRMED|
           1|2021-07-03 15:00:00|CONFIRMED|
           1|2021-07-03 15:00:00|CONFIRMED|
           1|2021-07-03 15:00:00|CONFIRMED|
           1|2021-07-03 15:00:00|CONFIRMED|
           1|2021-07-03 15:00:00|CONFIRMED|
           1|2021-07-03 15:00:00|CONFIRMED|

我需要的是展示那些"fightEventId"有超过2次CONFIRMED战斗的s。目前所有记录都以正确的方式排序,所以我期望的结果是:

fightEventId|
------------+
           2|
           1|

我该怎么做呢?每次我尝试时,我都会出错或订单被破坏。

至于项目中使用的 DBMS,它是 PostgreSQL,但我写的是 MySQL,因为我很确定有两种解决方案可以同时使用。

附言

这个查询来自我正在使用的 ORM,所以请不要与那些trues 和falses 混淆。:)

标签: sqlpostgresql

解决方案


您只需使用聚合和having

select fightEventId
from t
where status = 'CONFIRMED'
group by fightEventId
having count(*) > 2;

在您的查询中:

select fightEventId 
from location_time_slot lts join
     fight_events fe
     on lts."fightEventId" = fe.id join
     fights f on lts.id = f."slotId"
where f.status = 'CONFIRMED' and
      (now() at time zone 'utc' >= fe."from" and now() at time zone 'utc' <= fe."to" 
      ) or
      now() at time zone 'utc' <= fe."to" or
      now() at time zone 'utc' > fe."to"
group by fightEventId
having count(*) > 2
order by max(fe."from");

推荐阅读