【问题标题】:FInding the the most frequent value for a particular year in postgres在 postgres 中查找特定年份的最常见值
【发布时间】:2021-05-11 06:10:02
【问题描述】:

在 postgre 中,我想找到 2011 年对以下数据库的“打开”请求数量最多的用户。我是 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

这只是数据库的一小部分,总共大约有 250,000 个元组。

【问题讨论】:

  • 到目前为止您尝试过什么吗?可能涉及wheregroup bysumorder by
  • your other question 非常相似;如果你想要 2011 年,你应该删除关于提取月份的 SQL,并添加 where 子句: date>='2011-01-01' 和 date

标签: sql database postgresql dataset


【解决方案1】:

您不能嵌套聚合,并且无论如何您都需要按计数排序的整个顶行:

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;

按日期过滤的最佳方法是使用半开区间,即&gt;= start and &lt; dayAfterEnd

【讨论】:

  • 这会给出 2011 年“打开请求”数量最多的人的单个输出还是多个输出?
  • 查询应该输出2011年“opened”请求数最多的人的姓名,而不是所有请求
  • 但是你没有在请求类型上放置任何过滤器,它应该只是“打开”的请求!
  • 您是否需要那些在任何时候都已打开、仍在打开或在 2011 年底仍在打开的?
  • 我只需要请求列中“打开”的元组
【解决方案2】:

请你试试下面的方法

 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;

【讨论】:

  • 我提供的元组只是实际数据库的一小部分,实际数据库包含 250,000 个元组......
  • 我已经编辑了问题,请看一下
  • 已修改。请看一下
【解决方案3】:

您正在寻找不止一个人。这建议使用窗口函数:

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;

或者如果你使用 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

【讨论】:

    猜你喜欢
    • 2013-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-27
    • 2015-06-20
    • 1970-01-01
    • 2013-09-05
    相关资源
    最近更新 更多