【问题标题】:row_number() over partition in hql在 hql 中的分区上的 row_number()
【发布时间】:2014-05-11 18:20:07
【问题描述】:

hql 中分区上的 row_number() 等价物是什么 我在 hql 中有以下查询:

select s.Companyname, p.Productname, sum(od.Unitprice * od.Quantity - od.Discount) as SalesAmount FROM OrderDetails as od inner join od.Orders as o inner join od.Products as p " +
                                                              "inner join p.Suppliers as s" +
                                                      " where o.Orderdate between '2010/01/01' and '2014/01/01' GROUP BY s.Companyname,p.Productname"

我想通过s.Companyname 进行分区,其中RowNumber <= n

【问题讨论】:

    标签: hql window-functions


    【解决方案1】:

    按分区的行号如下所示:

    row_number() over (partition by s.Companyname)
    

    你不能在where子句中使用窗口函数row_number,所以你必须用它的值过滤子查询:

    select * from (
      -- here is your query
      select 
        ...,
        row_number() over (partition by s.Companyname) as rowNum
      from ...
      where ...
    ) as res
    where rowNum <= n
    

    【讨论】:

      【解决方案2】:

      据我所知,row_number() 既不能用于 HQL,也不能用于 JPQL。在这种情况下,我建议使用native SQL 查询:

      @PersistenceContext
      protected EntityManager entityManager;
      ...
      
          String sQuery = "SELECT q.* FROM (" +
                  "SELECT s.company_name, " +
                     "p.product_name, " +
                     "sum(od.unit_price * od.quantity - od.discount) as SalesAmount, " +
                     "row_number() OVER (partition by s.company_name) as rn " +
                  "FROM OrderDetails od " +
                  "INNER JOIN Orders o ON o.id = od.order_id " +
                  "INNER JOIN Products p ON p.id = od.product_id " +
                  "INNER JOIN Suppliers s ON s.id = p.supplier_id " +
                  "WHERE o.order_date between '2010/01/01' and '2014/01/01') as q " +
              "WHERE rn <= :n";
      
          List<ResultDbo> results = new ArrayList<>();
          Query query = entityManager.createNativeQuery(sQuery);
          query.setParameter("n", n);
          List<Object[]> resultSet = query.getResultList();
          for (Object[] resultItem : resultSet) {
              ResultDbo result = new ResultDbo();
              result.setCompanyName((String) resultItem[0]);
              result.setProductName((String) resultItem[1]);
              result.setSalesAmount((String) resultItem[2]);
              results.add(result);
          }
      

      如果您曾经尝试在 HQL 中使用 OVER(),您几乎肯定会遇到一些验证异常,例如 java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: OVER near line 1, column 42 ...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多