【问题标题】:Complex projections for Grails criteriaGrails 标准的复杂预测
【发布时间】:2016-06-21 16:25:28
【问题描述】:

我正在寻找以 Grails(或只是 Hibernate)标准形式表达以下 SQL 的方式。

select 
    sum(if( r.type = 'a', r.amount, 0)) as sum_a,    
    sum(if( r.type = 'b', r.amount, 0)) as sum_b    
from records r;

在这里,我想获得由特定列定义的不同行子集的两个总和。目标是在一个请求中获取它们。

嗯,看看 Projections 类,我发现它只为属性提供了一个基本的总和聚合,所以预期的答案是否定的,但最好的解决方案是什么?

【问题讨论】:

    标签: hibernate grails hibernate-criteria


    【解决方案1】:

    你应该看看 sqlProjection,它允许你写一些原生投影。

    也许它会是这样的:

    Projections.sqlProjection("sum(if( {alias}.type = 'a', {alias}.amount, 0)) as sum_a",   new String[] { "sum_a" }, new Type[] { StandardBasicTypes.INTEGER})
    

    【讨论】:

    • 在 groovy 语言中,您不能使用 java 语法 (new String[]{"one","two"}) 创建数组,因为 groovy 为闭包保留花括号,您可以使用以下语法:["一","二"].toArray()
    【解决方案2】:

    您可以在sqlGroupProjection 表达式中使用CASE...WHEN hibernate 语句,如下所示:

    Records.createCriteria().list{
        projections {
          sqlGroupProjection '(case type when \'a\' then sum(amount) else 0 end) as sum_a, (case type when \'b\' then sum(amount) else 0 end) as sum_b', 'type', ['sum_a', 'sum_b'], [INTEGER, INTEGER]
        }
    }
    

    这会生成以下 SQL:

    select (case type when 'a' then sum(amount) else 0 end) as sum_a, (case type when 'b' then sum(amount) else 0 end) as sum_b from records this_ group by type
    

    它对我有用,希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2011-01-20
      • 1970-01-01
      • 2012-11-25
      • 2013-01-22
      • 2023-03-13
      • 1970-01-01
      • 2012-08-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多