HQL:按月分组

时间:2009-05-29 16:36:52

标签: hibernate postgresql group-by

我正在尝试按月使用HQL对某些行进行分组,但我对该API并不熟悉,似乎无法使其工作。

这是我的代码:

        Criteria query = getHibernateSession().createCriteria(SalesPerformance.class);

        // summary report is grouped by date
        query.setProjection(Projections.projectionList().add(
                Projections.groupProperty("effectiveDate"), "effectiveDate").add(
                Projections.groupProperty("primaryKey.seller", "seller").add(
                Projections.sum("totalSales"))));


        // sub-select based on seller id
        query.add(Property.forName("primaryKey.seller.id").eq(sellerId)).setFetchMode(
                "primaryKey.seller", FetchMode.SELECT);

        query.add(Property.forName("primaryKey.effectiveDate").le(new Date()));
        query.add(Property.forName("primaryKey.effectiveDate").ge(DateUtils.truncate(new Date(), Calendar.MONTH)));
        query.addOrder(Order.desc("primaryKey.effectiveDate"));

        return query.list();

我对此查询的问题是,由于Projections.groupProperty(“effectiveDate”),当我每月需要一行时,它每天会返回一行。

我考虑过使用Projections.sqlGroupProjection而不是Projections.groupProperty并抛出一些HQL,但是我发现的文档和几个例子并没有真正帮助我理解如何在该方法中使用正确的postresql语句

任何了解Postgres和HQL的人都可以提供一些提示吗?

1 个答案:

答案 0 :(得分:6)

找到解决方案:

Criteria query = getHibernateSession().createCriteria(SalesPerformance.class);

    // summary report is grouped by date
            query.setProjection(Projections.projectionList().add(Projections.sqlGroupProjection("date_trunc('month', eff_dt) as eff_dt_value", "eff_dt_value", new String[] {"eff_dt_value"}, new Type[] {Hibernate.DATE})).add(
                            Projections.groupProperty("primaryKey.seller", "seller").add(
                            Projections.sum("totalSales"))));


            // sub-select based on seller id
            query.add(Property.forName("primaryKey.seller.id").eq(sellerId)).setFetchMode(
                            "primaryKey.seller", FetchMode.SELECT);

            query.add(Property.forName("primaryKey.effectiveDate").le(new Date()));
            Date beginningOfLastMonth = DateUtils.truncate(DateUtils.addMonths(new Date(), -1) , Calendar.MONTH);
            Date endOfLastMonth = DateUtils.addDays(DateUtils.truncate(new Date(), Calendar.MONTH), -1);
            query.add(Property.forName("primaryKey.effectiveDate").between(beginningOfLastMonth, endOfLastMonth));


            return query.list();

请注意,在我的情况下,我需要从上个月使用effectiveDate获取值。

希望这将有助于其他人在同一条船上! :)