使用GROUP BY和MIN与HSQLDB

时间:2013-05-24 10:50:44

标签: mysql sql database hsqldb


我需要执行一个查询,以便为每个客户检索具有最快过期日期的项目 我有以下产品表:

PRODUCT
 |ID|NAME |EXPIRE_DATE|CUSTOMER_ID
  1 |p1   |2013-12-31 |1
  2 |p2   |2014-12-31 |1
  3 |p3   |2013-11-30 |2

我希望得到以下结果:

|ID|EXPIRE_DATE|CUSTOMER_ID
 1 |2013-12-31 |1
 3 |2013-11-30 |2

使用Mysql我会得到一个类似的查询:

 SELECT ID,min(EXPIRE_DATE),CUSTOMER_ID
 FROM PRODUCT
 GROUP BY CUSTOMER_ID

但我使用的是HyperSQL,但我无法获得此结果 使用HSQLDB,我收到此错误:java.sql.SQLSyntaxErrorException: expression not in aggregate or GROUP BY columns: PRODUCT.ID
如果在HyperSQL中我修改了查询的最后一行,如GROUP BY CUSTOMER_ID,ID,我获得原始表的相同条目。

如何使用HSQLDB

为每个客户计算最快过期日期的产品

3 个答案:

答案 0 :(得分:1)

MySQL允许非ANSI组通常可以给出错误的结果。 HSQL正常运行。

有两个选项:

删除ID

SELECT min(EXPIRE_DATE),CUSTOMER_ID
 FROM PRODUCT
 GROUP BY CUSTOMER_ID

或者,假设ID随EXPIRE_DATE增加

SELECT MIN(ID),min(EXPIRE_DATE),CUSTOMER_ID
 FROM PRODUCT
 GROUP BY CUSTOMER_ID

如果你确实需要ID,那么你必须加入

SELECT
     P.ID, P.EXPIRE_DATE, P.CUSTOMER_ID
FROM
     (
     SELECT min(EXPIRE_DATE) AS minEXPIRE_DATE,CUSTOMER_ID
     FROM PRODUCT
     GROUP BY CUSTOMER_ID
     ) X
     JOIN
     PRODUCT P ON X.minEXPIRE_DATE = P.EXPIRE_DATE AND X.CUSTOMER_ID = P.CUSTOMER_ID

但是,我认为HSQL支持任何聚合。这给出了每MIN / GROUP BY的任意ID。

 SELECT ANY(ID),min(EXPIRE_DATE),CUSTOMER_ID
 FROM PRODUCT
 GROUP BY CUSTOMER_ID

答案 1 :(得分:1)

在MySQL中,您为每个客户获得了一个任意id。在SQL的大多数其他方言中,您需要指定所需的方法。这将有效:

SELECT min(ID), min(EXPIRE_DATE), CUSTOMER_ID
 FROM PRODUCT
 GROUP BY CUSTOMER_ID;

如果您尝试将id与最短的过期日期相关联,那么MySQL就不会这样做了。这是一种方法:

select p.*
from Product p join
     (select customer_id, min(Expire_date) as min_ed
      from Product p
      group by customer_id
     ) psum
     on p.customer_id = psum.customer_id and p.Expire_date = psum.min_ed

这是标准的SQL,可以在任何数据库上运行(尽管某些数据库具有更清洁,更高效的功能)。

答案 2 :(得分:0)

假设支持子查询,您可以将表连接到自身,如:

SELECT P.ID, P.EXPIRE_DATE, P.CUSTOMER_ID
FROM PRODUCT P
   JOIN (
       SELECT CUSTOMER_ID, MIN(EXPIRE_DATE) MIN_EXPIRE_DATE
       FROM PRODUCT
       GROUP BY CUSTOMER_ID
   ) P2 ON P.CUSTOMER_ID = P2.CUSTOMER_ID
        AND P.EXPIRE_DATE = P2.MIN_EXPIRE_DATE