[英]Correct sql/hql query (aggregate in where clause)
我想查询如下。 查询错误但描述了我的意图。
SELECT name, dateTime, data
FROM Record
WHERE dateTime = MAX(dateTime)
更新:好的。 该查询描述的意图不太好。 我的错。
我想为每个人选择最新记录。
尝试这个:
SELECT name, dateTime, data
FROM Record
WHERE dateTime = SELECT MAX(dateTime) FROM Record
您也可以使用内部联接编写它:
SELECT R.name, R.dateTime, R.data
FROM Record R
INNER JOIN (SELECT MAX(dateTime) FROM Record) RMax ON R.dateTime = RMax.dateTime
这是相同的,但从不同的角度写
SELECT R.name, R.dateTime, R.data
FROM Record R,
(SELECT MAX(dateTime) FROM Record) RMax
WHERE R.dateTime = RMax.dateTime
在MySQL
和PostgreSQL
:
SELECT name, dateTime, data
FROM Record
ORDER BY
dateTime DESC
LIMIT 1
在SQL Server
:
SELECT TOP 1 name, dateTime, data
FROM Record
ORDER BY
dateTime DESC
在Oracle
SELECT *
FROM (
SELECT name, dateTime, data
FROM Record
ORDER BY
dateTime DESC
)
WHERE rownum = 1
更新:
要为每个记录选择一个人,请在SQL Server
中使用:
WITH q AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY person ORDER BY dateTime DESC)
FROM Record
)
SELECT *
FROM q
WHERE rn = 1
或这个:
SELECT ro.*
FROM (
SELECT DISTINCT person
FROM Record
) d
CROSS APPLY
(
SELECT TOP 1 *
FROM Record r
WHERE r.person = d.person
ORDER BY
dateTime DESC
) ro
在我的博客中看到这篇文章:
了解两种解决方案的优缺点。
我喜欢Miky的回答和来自Quassnoi(并且赞成Miky's),但是,如果你的需求与我的相似,你应该记住一些限制。 首先也是最重要的是,它只适用于您要查找单个名称的最新记录或最新记录。 如果你想要一组中每个人的最新记录(每人一个记录,但每个人的最新记录),那么上述解决方案就会失败。 其次,不太重要的是,如果您将使用大型数据集,从长远来看可能会有点慢。 那么,解决方法是什么?
我所做的是在标有“最新”的表格中添加一个位字段。 然后,当我存储一条记录(在SQL Server中的存储过程中完成)时,我遵循以下模式:
Update Table Set Newest=0 Where Name=@Name
Insert into Table (Name, dateTimeVal, Data, Newest) Values (@Name, GetDate(), @Data, 1);
此外,Name和Newest上有一个索引可以使选择速度非常快。
那么Select就是:
Select dateTimeVal, Data From Table Where (Name=@Name) and (Newest=1);
选择一个组将是这样的:
Select Name, dateTimeVal, Data from Table Where (Newest=1); -- Gets multiple records
如果记录可能没有按日期顺序输入,那么您的逻辑有点不同:
Update Table Set Newest=0 Where Name=@Name
Insert into Table (Name, dateTimeVal, Data, Newest) Values (@Name, GetDate(), @Data, 0); -- NOTE ZERO
Update Table Set Newest=1 Where dateTimeVal=(Select Max(dateTimeVal) From Table Where Name=@Name);
其余的保持不变。
我尝试了Milky的建议,但构建子查询的所有三种方法都导致了HQL解析器错误。
但是,有效的是第一种方法略有改变(增加了额外的括号)。
SELECT name, dateTime, data
FROM Record
WHERE dateTime = (SELECT MAX(dateTime) FROM Record)
PS:这只是为了向HQL新手等指出明显的问题。 认为这会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.