Mysql 子查询和sql中的GROUPBY子句

Mysql 子查询和sql中的GROUPBY子句,mysql,Mysql,我们可以不使用子查询编写此查询吗 select * from test where EmpTran in (select max(EmpTran) from test); 我尝试了这段代码,但它返回空集。 我读到,“在没有GROUPBY的情况下,整个数据被视为一个单独的组”,如果是这种情况,查询应该返回与上面查询相同的结果 select EmpTran,EmpName from test having EmpTran = max(EmpTran); 样本数据: create table

我们可以不使用子查询编写此查询吗

select * from test where EmpTran in
(select max(EmpTran) from test);
我尝试了这段代码,但它返回空集。 我读到,“在没有GROUPBY的情况下,整个数据被视为一个单独的组”,如果是这种情况,查询应该返回与上面查询相同的结果

select EmpTran,EmpName from test
having EmpTran = max(EmpTran);
样本数据:

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

第二个查询不起作用,因为只要在查询中的任何位置使用聚合函数,就会导致行聚合。由于没有“分组依据”,所有内容都聚合到结果集中的一行中(正如您所引用的:如果没有“分组依据”,则将整个数据视为一个组)。在此结果集中,
EmpTran
EmpName
取自表中的任意行(它们甚至可能不来自同一行)

拥有
然后过滤此结果集。如果所选的
EmpTran
值与
MAX(EmpTran)
不匹配,则该行将从结果集中删除,并得到一个空结果

处理顺序如下:

  • 使用
    WHERE
    选择要放入结果集中的行
  • 如有必要,聚合结果集
  • 使用
    HAVING
    筛选聚合结果集

  • 我不认为在MySQL 5.x中没有子查询就可以做到这一点。在MySQL 8.x中,可以使用窗口函数(我不熟悉这些函数,所以我不会在回答中显示它)。

    第二个查询不起作用,因为只要在查询中的任何位置使用聚合函数,它就会导致行聚合。由于没有“分组依据”,所有内容都聚合到结果集中的一行中(正如您所引用的:如果没有“分组依据”,则将整个数据视为一个组)。在此结果集中,
    EmpTran
    EmpName
    取自表中的任意行(它们甚至可能不来自同一行)

    拥有
    然后过滤此结果集。如果所选的
    EmpTran
    值与
    MAX(EmpTran)
    不匹配,则该行将从结果集中删除,并得到一个空结果

    处理顺序如下:

  • 使用
    WHERE
    选择要放入结果集中的行
  • 如有必要,聚合结果集
  • 使用
    HAVING
    筛选聚合结果集

  • 我不认为在MySQL 5.x中没有子查询就可以做到这一点。在MySQL 8.x中,您可以使用窗口函数(我不熟悉这些函数,所以我不打算在回答中显示它)。

    正如Barmar已经解释的那样,您的第二个查询将不起作用,因为查找列的最大值需要一个正式的单独子查询。早于8+的MySQL版本就是这样。从引入窗口函数的MySQL 8+开始,我们可以尝试以下方法:

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


    演示是在SQL Server中进行的,因为Rextester还不支持MySQL 8+。但是,它应该在任何实现ANSI窗口函数标准的数据库上运行。

    正如Barmar已经解释的那样,第二个查询将不起作用,因为查找列的最大值需要一个正式的单独子查询。早于8+的MySQL版本就是这样。从引入窗口函数的MySQL 8+开始,我们可以尝试以下方法:

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


    演示是在SQL Server中进行的,因为Rextester还不支持MySQL 8+。但是,它应该在任何实现ANSI窗口函数标准的数据库上运行。

    我希望您的第一个查询返回一些内容,假设它实际上包含记录。你能为你的问题添加一些样本数据吗?我不能在有数据的样本表上添加数据。
    (从测试中选择max(EmpTran)
    ,因为这将是一个单一的值,你可以使用
    =
    而不是
    @Barmar中,我认为你是对的。附带说明,在MySQL 8+中使用
    MAX()OVER()
    作为一个分析函数,我们实际上可以做一些非常接近这一点的事情。将其作为单个查询来做可能不会更快。它仍然需要做同样的工作:首先找到最大值,然后扫描所有行以查看它们是否匹配该最大值。如果您在
    EmpTran
    列上添加索引,应该会很快。我希望您的第一个查询返回一些内容,假设其中确实有记录。你能为你的问题添加一些样本数据吗?我不能在有数据的样本表上添加数据。
    (从测试中选择max(EmpTran)
    ,因为这将是一个单一的值,你可以使用
    =
    而不是
    @Barmar中,我认为你是对的。附带说明,在MySQL 8+中使用
    MAX()OVER()
    作为一个分析函数,我们实际上可以做一些非常接近这一点的事情。将其作为单个查询来做可能不会更快。它仍然需要做同样的工作:首先找到最大值,然后扫描所有行以查看它们是否匹配该最大值。如果在
    EmpTran
    列上添加索引,应该会很快。我的第二个查询不起作用,因为查找列的最大值需要一个正式的单独子查询,但为此,我们有group by和having。如果没有group by,则整个数据被视为一个组,因此它应该可以工作。@Anshuman_Jha不,您的第二个查询甚至不会在大多数其他数据库上运行。在调用
    MAX
    而不调用
    groupby
    时,您是在告诉数据库在整个表级别执行操作,而不是在单个记录级别执行操作。因此,您的第二个查询甚至没有任何意义。“在整个表级别执行任务”这与表中的所有行不一样吗?不,不是。您可以在组/表模式或记录级模式下运行查询。实际上,我的答案有点两者兼而有之,在执行查询的同时生成一个表级最大值。但是,它仍然需要一个子查询。我的第二个查询不起作用,因为查找列的最大值需要一个正式的单独子查询,b