使用executeQuery() 在算术表达式上进行Grails 投影?

发布于 2024-12-07 22:02:45 字数 1013 浏览 0 评论 0原文

我需要获得每个商店每个订单销售的所有商品的总和。我正在使用executeQuery() 对表达式运行sum()。它工作得很好,如下所示,但我想知道是否有更好、更绝妙的方法来做到这一点。

StoreService {
  static transactional = false

  def getTotalOrders(def store) {
    return Store.executeQuery("select sum(a.soldQuantity * a.soldPrice) as total 
             from OrderItem a inner join a.order b inner join b.store c 
             where c= :store", [store: store]).get(0)
  }
}

Store {
  transient storeService

  def getTotalSales() {
    storeService.getTotalSales()
  }

  static hasMany = [items: Item]
  // no hasMany to Order
}

Item {
  static belongsTo = [store: Store]
  // no hasMany to OrderItem
}


Order {
  static hasMany = [orderItems: OrderItem]
  static belongsTo = [store: Store]
}


OrderItem {

  BigDecimal soldPrice
  Integer soldQuantity

  static belongsTo = [order: Order, item: Item]

}

我认为 withCriteria() 会更容易阅读,但我不知道如何使用 sum() 中的表达式来执行此操作,原因很明显。

projections {
  sum("soldPrice * soldQuantity")
}

谢谢

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 there is a better, groovier way to do it.

StoreService {
  static transactional = false

  def getTotalOrders(def store) {
    return Store.executeQuery("select sum(a.soldQuantity * a.soldPrice) as total 
             from OrderItem a inner join a.order b inner join b.store c 
             where c= :store", [store: store]).get(0)
  }
}

Store {
  transient storeService

  def getTotalSales() {
    storeService.getTotalSales()
  }

  static hasMany = [items: Item]
  // no hasMany to Order
}

Item {
  static belongsTo = [store: Store]
  // no hasMany to OrderItem
}


Order {
  static hasMany = [orderItems: OrderItem]
  static belongsTo = [store: Store]
}


OrderItem {

  BigDecimal soldPrice
  Integer soldQuantity

  static belongsTo = [order: Order, item: Item]

}

I think withCriteria() would be easier to read but I couldn't figure out how to do it with expressions within sum() wouldn't take for obvious reasons.

projections {
  sum("soldPrice * soldQuantity")
}

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一梦浮鱼 2024-12-14 22:02:45

您可以选择两种选择。

选项 1

您可以将公式映射添加到您的域类,然后直接查询它。

OrderItem {
  BigDecimal soldPrice
  Integer soldQuantity
  BigDecimal totalPrice

  static mapping = {
    totalPrice formula: "sold_price * sold_quantity"
  }

  static belongsTo = [order: Order, item: Item]

}

现在,您的条件查询可以只包含

projections {
    sum("totalPrice")
}

不仅如此,您还可以使用动态查找器OrderItem.findAllByTotalPriceGreaterThan(20.00)以及简单的访问println“最终价格为${orderInstance.totalPrice”来查询它我们发现这确实很漂亮,但是有时您希望在 OrderItem 被持久化之前获取totalPrice,所以我们通常编写一个简单的(不是DRY) getter

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

但如果您在持久化之前需要 TotalPrice,则只需要这种东西

选项 2

在公式映射之前,我们通常会下拉到 Hibernate Criteria API 并使用 sqlProjection 投影作为我们的一部分。 。

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

注意

我认为重要的是要注意,在公式和 sql 投影中,请使用数据库中的列名称以及数据库特定的总和语法

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.

清音悠歌 2024-12-14 22:02:45

从 Grails 2.2 开始,支持 SQL 投影,而无需下拉到 Hibernate Criteria API。请注意,公式映射可能仍然更理想,但是这样您就可以根据您的问题直接实现 sum('soldPrice * sellQuantity') 样式投影。

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

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

你与昨日 2024-12-14 22:02:45

我尝试添加瞬态 派生属性 totalOrderItem 并使用sum() 就可以了。

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

水染的天色ゝ 2024-12-14 22:02:45

尝试 SQL 投影

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

了解更多详细信息
http://docs.grails.org/2.5.6/guide/ GORM.html#criteria

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文