简体   繁体   English

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

[英]Correct sql/hql query (aggregate in where clause)

I want to do query as below. 我想查询如下。 Query is wrong but describes my intentions. 查询错误但描述了我的意图。

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

Update: Ok. 更新:好的。 The query describes intentions not quite good. 该查询描述的意图不太好。 My bad. 我的错。

I want to select latest record for each person. 我想为每个人选择最新记录。

Try This: 尝试这个:

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

You could also write it using an inner join: 您也可以使用内部联接编写它:

SELECT R.name, R.dateTime, R.data
FROM Record R
  INNER JOIN (SELECT MAX(dateTime) FROM Record) RMax ON R.dateTime = RMax.dateTime

Which is the same but written from a different perspective 这是相同的,但从不同的角度写

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

In MySQL and PostgreSQL : MySQLPostgreSQL

SELECT  name, dateTime, data
FROM    Record
ORDER BY
        dateTime DESC
LIMIT 1

In SQL Server : SQL Server

SELECT  TOP 1 name, dateTime, data
FROM    Record
ORDER BY
        dateTime DESC

In Oracle Oracle

SELECT  *
FROM    (
        SELECT  name, dateTime, data
        FROM    Record
        ORDER BY
                dateTime DESC
        )
WHERE   rownum = 1

Update: 更新:

To select one person for each record, in SQL Server , use this: 要为每个记录选择一个人,请在SQL Server中使用:

WITH    q AS
        (
        SELECT  *, ROW_NUMBER() OVER (PARTITION BY person ORDER BY dateTime DESC)
        FROM    Record
        )
SELECT  *
FROM    q
WHERE   rn = 1

or this: 或这个:

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

See this article in my blog: 在我的博客中看到这篇文章:

for benefits and drawbacks of both solutions. 了解两种解决方案的优缺点。

I like Miky's answer and the from Quassnoi (and upvoted Miky's) but, if your needs are similar to mine, you should keep in mind some limitations. 我喜欢Miky的回答和来自Quassnoi(并且赞成Miky's),但是,如果你的需求与我的相似,你应该记住一些限制。 First and most importantly, it only works if you are looking for the latest record overall or the latest record for a single name. 首先也是最重要的是,它只适用于您要查找单个名称的最新记录或最新记录。 If you want the latest record for each person in a set (one record per person but the latest record for each) then the above solutions fall short. 如果你想要一组中每个人的最新记录(每人一个记录,但每个人的最新记录),那么上述解决方案就会失败。 Second, and less importantly, if you'll be working with large datasets, might prove a bit slow over the long run. 其次,不太重要的是,如果您将使用大型数据集,从长远来看可能会有点慢。 So, what is the work-around? 那么,解决方法是什么?

What I do is to add a bit field to the table marked "newest." 我所做的是在标有“最新”的表格中添加一个位字段。 Then, when I store a record (which is done in a stored procedure in SQL Server) I follow this pattern: 然后,当我存储一条记录(在SQL Server中的存储过程中完成)时,我遵循以下模式:

Update Table Set Newest=0 Where Name=@Name
Insert into Table (Name, dateTimeVal, Data, Newest) Values (@Name, GetDate(), @Data, 1);

Also, there is an index on Name and Newest to make Selects very fast. 此外,Name和Newest上有一个索引可以使选择速度非常快。

Then the Select is just: 那么Select就是:

Select dateTimeVal, Data From Table Where (Name=@Name) and (Newest=1);

A select for a group will be something like: 选择一个组将是这样的:

Select Name, dateTimeVal, Data from Table Where (Newest=1);  -- Gets multiple records

If the records may not be entered in date order, then your logic is a little bit different: 如果记录可能没有按日期顺序输入,那么您的逻辑有点不同:

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);

The rest stays the same. 其余的保持不变。

I tried Milky's advice but all three ways of constructing subquery resulted in HQL parser errors. 我尝试了Milky的建议,但构建子查询的所有三种方法都导致了HQL解析器错误。

What does work though, is a slight change to the first method (added extra parentheses). 但是,有效的是第一种方法略有改变(增加了额外的括号)。

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

PS: This is just for pointing out the obvious to HQL newbies and the like. PS:这只是为了向HQL新手等指出明显的问题。 Thought it would help. 认为这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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