我需要执行一个查询,以便为每个客户检索具有最快过期日期的项目
我有以下产品表:
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
答案 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