【问题标题】:How to group results by intervals?如何按间隔对结果进行分组?
【发布时间】:2010-08-05 14:49:11
【问题描述】:

我有一个包含具有“速度”属性的事件的表。

为了查看这个属性的统计分布,我想按区间对结果进行分组,比如说:

[0-49.99km/h] 3 objects
[50-100km/h] 13 objects
[100-150km/h] 50 objects
etc

这会让我看到大多数对象都在某个区间内。

显然,这可以通过具有适当 Where 条件的多个查询来完成,例如:

从 GaEvent a 中选择计数,其中速度 >= MIN 和速度

但这是非常低效的。 有没有更好的方法对这些值进行分组?

干杯!

【问题讨论】:

    标签: java sql hibernate group-by


    【解决方案1】:

    仅在 SQL 中解决此问题的更有效方法是将相关表与派生表连接起来,该派生表包含您想要在直方图中显示的最小值和最大值。

    例如:

    select t.min, t.max, count(*)
    from  (
        select 0 as min, 14.9 as max
        union 
        select 15, 29.9
        union
        select 30, 44.9
        union ...
    ) t
    left outer join cars c on c.speed between t.min and t.max
    group by t.min, t.max
    order by t.min
    
    min | max  | count
    -----------------
     0  | 14.9 | 1
     15 | 29.9 | 1
     30 | 44.9 | 2
    

    这在很大程度上取决于您使用的数据库供应商。例如,PostgreSQL 有一个window functions 的概念,它可能会大大简化这种类型的查询,并避免您需要自己生成“直方图”。

    不过,当谈到 Hibernate 时,Projectionssupport for aggregrate functions 的方式似乎很少适用于这样的任何事情。这很可能是您希望直接使用原始 SQL 进行查询和/或在 Java 本身中进行计算的场景。

    【讨论】:

    • 谢谢!我在 PostGreSQL 上的 Grails 上使用 Hibernate。目前我用多个查询解决了这个问题,但它非常非常慢。你知道这是否可以在 HQL 中完成吗?我不想失去数据库独立性。干杯
    • 我非常怀疑,因为 HQL 的目标并不完全适合您想要运行的查询类型。事实上,我不认为 HQL 可以处理对非实体/非映射表的查询。此外,HQL 的结构是返回作为实体的结果实例,而不是任意查询的结果(您希望在直方图中返回每行的最小/最大/计数等)
    【解决方案2】:

    如果你的间隔都是相同的大小,你可以使用这样的东西:

    select 50*trunc(c.speed/50), count(*) from Car c group by 1

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-30
      • 2015-01-05
      相关资源
      最近更新 更多