繁体   English   中英

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

[英]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

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

在我的博客中看到这篇文章:

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

我喜欢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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM