【问题标题】:Getting the min() of a count(*) column获取 count(*) 列的 min()
【发布时间】:2011-06-07 00:21:52
【问题描述】:

我有一个名为 Vehicle_Location 的表,其中包含列(以及更多):

ID               NUMBER(10)
SEQUENCE_NUMBER NUMBER(10) 
TIME            DATE 

我正在尝试获取每个 id 每天的最小/最大/平均记录数。

到目前为止,我已经

select id, to_char(time), count(*) as c
  from vehicle_location
 group by id, to_char(time), min having id = 16

这给了我:

ID                     TO_CHAR(TIME) COUNT(*)               
---------------------- ------------- ---------------------- 
16                     11-05-31      159                    
16                     11-05-23      127                             
16                     11-06-03      56                  

所以我想获得 count(*) 列的 min/max/avg。我使用 Oracle 作为我的 RDBMS。

【问题讨论】:

  • 次要问题,但使用TO_CHAR(TIME) 获取日期组件依赖于您将NLS_DATE_FORMAT 设置为不包含时间的内容。更常见的方法是使用TRUNC(TIME)。在这种情况下,我会将过滤器放在id = 16where 子句中,而不是having 子句中,因为它不需要在分组后进行评估 - 两者都可以,但你可能会遇到索引使用where

标签: sql oracle


【解决方案1】:

我没有要测试的 oracle 站,但您应该能够将聚合器包装在您的 SELECT 周围作为子查询/派生表/内联视图

所以它会是(未经测试!!)

SELECT 
    AVG(s.c)
    , MIN(s.c)
    , MAX(s.c)
    , s.ID
FROM
    --Note this is just your query
    (select id, to_char(time), count(*) as c from vehicle_location group by id, to_char(time), min having id = 16) as s
GROUP BY s.ID

这里有一些关于它的阅读:
http://www.devshed.com/c/a/Oracle/Inserting-SubQueries-in-SELECT-Statements-in-Oracle/3/

编辑:虽然通常在单个查询中选择两者MINMAX 是一个 的想法。

EDIT2: 最小/最大问题与某些 RDBMS(包括 oracle)如何处理索引列上的聚合有关。它可能不会影响这个特定的查询,但前提是使用索引很容易找到MIN MAX 但不能同时找到两者,因为任何索引都可能不会有效地使用。
这里有一些关于它的阅读:
http://momendba.blogspot.com/2008/07/min-and-max-functions-in-single-query.html

【讨论】:

  • 为什么在单个查询中同时选择 MIN 和 MAX 是个坏主意?
  • 我说通常是因为某些 RDBMS(包括 Oracle)如何计划 MINMAX 查询。它可以快速获取其中一个,但是当您同时要求两者时,它可能不知道要使用哪个索引。我已经编辑了我的答案。
猜你喜欢
  • 1970-01-01
  • 2022-12-05
  • 2016-08-26
  • 2021-12-25
  • 2020-10-28
  • 1970-01-01
  • 2020-12-27
  • 2019-02-11
  • 2014-09-06
相关资源
最近更新 更多