简体   繁体   中英

Sub-Query and having group by clause in sql

Can we write this query without using sub-query?

select * from test where EmpTran in
(select max(EmpTran) from test);

I tried this code but it returns empty set. I read that, 'in absence of group by, entire data is taken as a single group', if that's the case the the query should return same result as the query above.

select EmpTran,EmpName from test
having EmpTran = max(EmpTran);

Sample data:

  create table test(EmpName varchar(10),EmpTrans int);
  insert into test values('Ans',100);
  insert into test values('Sam',50);
  insert into test values('Kar',150);
  insert into test values('Sar',200);
  insert into test values('Raj',200);

The second query doesn't work because as soon as you use an aggregation function anywhere in the query, it causes the rows to be aggregated. Since you don't have GROUP BY , everything is aggregated into a single row in the result set (just as you quoted: in absence of group by, entire data is taken as a single group ). In this result set, EmpTran and EmpName are taken from arbitrary rows in the table (they might not even be from the same row).

HAVING then filters this result set. If the selected value of EmpTran doesn't match MAX(EmpTran) , the row is removed from the result set and you get an empty result.

The order of processing is:

  1. Use WHERE to select the rows to put in the result set.
  2. Aggregate the result set if necessary.
  3. Use HAVING to filter the aggregated result set.

I don't think there's a way to do this without a subquery in MySQL 5.x. In MySQL 8.x you can do it with a window function (I'm not familiar with these, so I'm not going to show it in my answer).

As Barmar has already explained, your second query won't work because finding the max of a column requires a formal separate subquery. This was the case for MySQL versions earlier than 8+. Starting with MySQL 8+, which introduced window functions, we could try something like this:

SELECT *
FROM
(
    SELECT *, MAX(EmpTran) OVER () max_val
    FROM test
) t
WHERE EmpTran = max_val;

Demo

The demo is in SQL Server, because Rextester does not yet support MySQL 8+. But, it should run on any database which implements the ANSI standard for window functions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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