正确的sql / hql查询(在where子句中聚合)

时间:2010-01-22 14:48:34

标签: sql tsql hql

我想查询如下。查询错误但描述了我的意图。

SELECT name, dateTime, data
FROM Record
WHERE dateTime = MAX(dateTime)

更新:好的。该查询描述的意图不太好。我的坏。

我想为每个人选择最新记录。

4 个答案:

答案 0 :(得分:5)

试试这个:

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

答案 1 :(得分:2)

MySQLPostgreSQL

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

在我的博客中查看此文章:

了解两种解决方案的优缺点。

答案 2 :(得分:2)

我喜欢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);

其余的保持不变。

答案 3 :(得分:0)

我尝试了Milky的建议,但构建子查询的所有三种方法都导致了HQL解析器错误。

虽然有效,但第一种方法略有改变(增加了额外的括号)。

SELECT name, dateTime, data
FROM Record 
WHERE dateTime = (SELECT MAX(dateTime) FROM Record)

PS:这只是为了向HQL新手等指出明显的问题。认为这会有所帮助。