Grails projection on arithmetic expression with executeQuery()?

前端 未结 4 1484
栀梦
栀梦 2021-01-14 09:26

I need to get a sum of all items sold per order per store. I am running a sum() on expression using executeQuery(). It works fine as shown below but I wanted to know if ther

相关标签:
4条回答
  • 2021-01-14 09:49

    Try SQL Projection

    projections {
      sqlProjection 'sum("soldPrice * soldQuantity") as total', 'total', StandardBasicTypes.DOUBLE
    }
    

    For farther details http://docs.grails.org/2.5.6/guide/GORM.html#criteria

    0 讨论(0)
  • 2021-01-14 10:00

    As of Grails 2.2, SQL projections are supported without having to drop down to the Hibernate Criteria API. Note that a formula mapping may still be more desirable, but with this you can directly implement the sum('soldPrice * soldQuantity') style projection as per your question.

    http://grails.org/doc/latest/guide/single.html#criteria

    0 讨论(0)
  • 2021-01-14 10:08

    I'd try to add a transient derived property total to OrderItem and use sum() on it.

    0 讨论(0)
  • 2021-01-14 10:14

    There are two options you can go with.

    Option 1

    You can add a formula mapping to your domain class then query it directly.

    OrderItem {
      BigDecimal soldPrice
      Integer soldQuantity
      BigDecimal totalPrice
    
      static mapping = {
        totalPrice formula: "sold_price * sold_quantity"
      }
    
      static belongsTo = [order: Order, item: Item]
    
    }
    

    Now your criteria query can just contain

    projections {
        sum("totalPrice")
    }
    

    Not only that but you can query it with dynamic finders OrderItem.findAllByTotalPriceGreaterThan(20.00) as well as simple access println "The final price is ${orderInstance.totalPrice}. We find this really nifty however there are times when you would want to get totalPrice before the OrderItem has been persisted so we usually write a simple(Not DRY) getter

    BigDecimal getTotalPrice() {
        totalPrice ?: (soldPrice && soldQuantity) ? soldPrice * soldQuantity : null
    }
    

    But you only need this sort of thing if you require totalPrice before it has been persisted.

    Option 2

    Before formula mappings we used to drop down to the Hibernate Criteria API and use a sqlProjection Projection as part of our criteria query.

    projections {
        addProjectionToList(Projections.sqlProjection(
                "sum(sold_price * sold_quantity) as totalPrice",
                ["totalPrice"] as String[], 
                [Hibernate.LONG] as Type[],
            ), "sumProjection")
     }
    

    Note

    I think it is important to note that in both the formula and the sql projection, use the column names in the database and your database specific sum syntax.

    0 讨论(0)
提交回复
热议问题