Grails GORM按CASE语句排序 [英] Grails GORM sort by CASE statement

查看:639
本文介绍了Grails GORM按CASE语句排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用 CASE 语句通过GORM查询进行排序。我所拥有的是一列 state 的视图,其值可以是状态缩写或单词 General 。我会运行这样的查询



pre $ Drop $ get $ ,order:asc]

但它返回一个错误

 无法解析属性:stateOrderBy:workspace.Dropdown 

当我创建类似以下的域类时, stateOrderBy 的值是字符串 CASE WHEN state ='General'THEN 2 ELSE 1 END 而不是1或2这就是为什么我得到上述错误。有没有一种方法来评估我的CASE语句?

  @EqualsAndHashCode(includeFields = true)
class Dropdown实现Serializable {
字符串状态
字符串dropDownNames
字符串sectionName
字符串前缀
整数displayOrder
def stateOrderBy =CASE WHEN state ='General'THEN 2 ELSE 1 END

static transients = [stateOrderBy]

静态映射= {
数据源'plDropdown'
表'view_AllTables'
id复合:['state','sectionName','displayOrder']
状态列:'状态'
dropDownNames列: 'DropDownNames'
sectionName列:'SectionName'
前缀列:'前缀'
displayOrder列:'DisplayOrder'
stateOrderBy列:'stateOrderBy'
版本false


编辑:总会有一个结果 General 列,但状态特定查询可能没有结果。如果有返回状态的具体答案,我想使用它,否则一般的答案。

解决方案

GORM / Hibernate排序是由域/实体属性。 GORM不会将一个属性评估为SQL语句。这是一件好事,因为它是危险的。

可以使用Criteria查询创建SqlProjection:

  Dropdown.withCriteria {'''''''''''''$'$'$' ('state')
属性('dropDownNames')
属性('sectionName')
属性('前缀')
属性('displayOrder ')

sqlProjectionCASE WHEN state ='General'THEN 2 ELSE 1 END as stateSortBy,'stateSortBy',org.hibernate.type.IntegerType as org.hibernate.type.Type
}

order('stateSortBy','asc')
}

这将创建一个即将被排序的属性。虽然我认为在视图中做同样的事情会更好。然后你可以通过该属性进行排序,即使使用动态搜索。



在上面的sqlProjection示例中, stateSortBy 动态创建的属性将包含值2或1.这可能不是您想要的,因此您需要用那些序号引用的表列名称替换它们。然后,您需要更改休眠类型适当的一个。这意味着两列必须是相同的类型或铸造。用SQL术语来说,你想要的是一个新的计算字段,其中包含要排序的值。

请注意,因为正在使用投影,结果将是一个包含投影属性(表格列)。它不会是一个List。



关于Domain.executeQuery()和Domain.findAll(sql),这些是用于HQL而不是SQL。


I'm trying to use a CASE statement to order by GORM query. What I have is a view with a column of state the value there can be a state abbreviation or the word General. I will run the query like this

Dropdown.findByStateInList(['General','CA'], [sort: "stateOrderBy", order: "asc"]

but it returns an error of

could not resolve property: stateOrderBy of: workspace.Dropdown

When I create my domain class like below the value of stateOrderBy is the string CASE WHEN state = 'General' THEN 2 ELSE 1 END and not a 1 or 2 which is why I'm getting the error above. Is there a way to evaluate my CASE statement?

@EqualsAndHashCode(includeFields=true)
class Dropdown implements Serializable {
  String state
  String dropDownNames
  String sectionName
  String prefix
  Integer displayOrder
  def stateOrderBy = "CASE WHEN state = 'General' THEN 2 ELSE 1 END"

  static transients = [ "stateOrderBy" ]

  static mapping = {
    datasource 'plDropdown'
    table 'view_AllTables'
    id composite: ['state','sectionName','displayOrder']
    state column:'state'
    dropDownNames column:'DropDownNames'
    sectionName column:'SectionName'
    prefix column:'Prefix'
    displayOrder column:'DisplayOrder'
    stateOrderBy column:'stateOrderBy'
    version false
  }
}

EDIT: There will always be a result in the General column, but there may not be a result for the state specific query. If there is a state specific answer returned I want to use that otherwise the General answer.

解决方案

GORM/Hibernate sorting is done by domain/entity properties. GORM will not evaluate a property as a SQL statement. That's a good thing because it's dangerous.

What might work is creating a SqlProjection with a Criteria query:

Dropdown.withCriteria {
    'in'('state', ['General','CA'])

    projections {
        property('state')
        property('dropDownNames')
        property('sectionName')        
        property('prefix')
        property('displayOrder')

        sqlProjection "CASE WHEN state = 'General' THEN 2 ELSE 1 END as stateSortBy", 'stateSortBy', org.hibernate.type.IntegerType as org.hibernate.type.Type
    }

    order('stateSortBy', 'asc')
}

That will create a property on the fly that would be sorted by. Although I think it would be better to do the equivalent in the view. Then you'd be able to sort by that property, even with a Dynamic Finder.

In the sqlProjection example above, the stateSortBy property that's created on the fly would contain the value 2 or 1. That's probably not want you want, so you'll need to replace those with the table column names those ordinals refer to. Then, you'll need to change the hibernate type to one that's appropriate. Which means the two columns must either be of the same type or be casted as such. In SQL terms, what you want is a new calculated field with the value to sort by.

Note that because projections are being used, the result will be a List containing the projected properties (table columns). It will not be a List.

About Domain.executeQuery() and Domain.findAll(sql), those are for HQL rather than SQL.

这篇关于Grails GORM按CASE语句排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆