简体   繁体   English

在 postgres 中查找特定年份的最常见值

[英]FInding the the most frequent value for a particular year in postgres

In postgre, I want to find the user(s) who has the highest number of "opened" requests in the year 2011 for the following database.在 postgre 中,我想找到 2011 年对以下数据库的“打开”请求数量最多的用户。 I am new to postgre and I am stuck with this.我是 postgre 的新手,我坚持这一点。


ID  PERSON      REQUEST   DATE
4   datanoise   opened  2008-09-02 
5   marsuboss   opened  2009-09-02 
6   m3talsmith  opened  2009-09-06 
7   sferik  opened  2010-09-08 
8   sferik  opened  2010-09-09 
8   dtrasbo discussed   2010-09-09 
8   brianmario  discussed   2011-09-09 
8   sferik  discussed   2011-09-09 
9   rsim    opened  2011-09-09 
.....more tuples to follow

this is just a small part of the database, there are around 250,000 tuples in total.这只是数据库的一小部分,总共大约有 250,000 个元组。

You can't nest aggregates, and in any case you need the whole top row ordered by count:您不能嵌套聚合,并且在任何情况下您都需要按计数排序的整个顶行:

select person, count(request) as countRequests
from table
where (date >= '2011-01-01' and date < '2012-01-01')
    and request = 'opened'
group by person
order by countRequests desc
limit 1;

The best way to filter by date is to use a half-open interval ie >= start and < dayAfterEnd按日期过滤的最佳方法是使用半开间隔,即>= start and < dayAfterEnd

Could you please try the following你能试试下面的

 WITH CTE(ID,PERSON,REQUEST,DATE) AS
  (
    SELECT 4,'datanoise','opened','2008-09-02'
       UNION ALL  
    SELECT 5,   'marsuboss',   'opened',  '2009-09-02' 
       UNION ALL
    SELECT 6 ,  'm3talsmith',  'opened' , '2009-09-06' 
       UNION ALL
    SELECT 7 ,  'sferik' , 'opened',  '2010-09-08' 
       UNION ALL
    SELECT 8 ,  'sferik',  'opened' , '2010-09-09' 
       UNION ALL
    SELECT 8 ,  'dtrasbo', 'discussed',   '2010-09-09' 
      UNION ALL
    SELECT 8 ,  'brianmario',  'discussed' ,  '2011-09-09' 
       UNION ALL
    SELECT 8 ,  'sferik',  'discussed',   '2011-09-09' 
       UNION ALL
    SELECT 9 ,  'rsim',    'opened',  '2011-09-09' 
   )
   SELECT C.PERSON,COUNT(C.ID)CNTT
      FROM CTE AS C
      WHERE C.DATE >= '2011-01-01'AND  C.DATE<'2012-01-01'
         AND C.REQUEST='OPENED'
      GROUP BY C.PERSON 
      ORDER BY COUNT(C.ID)DESC
      LIMIT 1;

You are looking for more than one person.您正在寻找不止一个人。 That suggests using window functions:这建议使用 window 函数:

SELECT P.*
FROM (SELECT T.PERSON, COUNT(*) AS CNT,
             RANK() OVER (OVER BY COUNT(*) DESC) AS SEQNUM
      FROM T
      WHERE T.DATE >= '2011-01-01'AND T.DATE < '2012-01-01' AND
            T.REQUEST = 'OPENED'
      GROUP BY T.PERSON 
     ) P
WHERE seqnum = 1;

Or if you are using Postgres 13+, you can use WITH TIES :或者,如果您使用的是 Postgres 13+,则可以使用WITH TIES

SELECT T.PERSON, COUNT(*) AS CNT
FROM T
WHERE T.DATE >= '2011-01-01'AND T.DATE < '2012-01-01' AND
      T.REQUEST = 'OPENED'
GROUP BY T.PERSON
ORDER BY COUNT(*) DESC
FETCH FIRST 1 ROW WITH TIES

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM