子查询中的最小/最大功能

时间:2017-11-05 16:33:00

标签: mysql sql

我有一个与SQL子查询相关的问题。我有一个数据集,其中包含2列:tasker_ID和working_hours,列如下所示:

    Tasker_ID   working_hours
       1              15
       2              17
       4              4
       1              28
       3              0
       2              17 
       4              23
       5              21
       2              19
       7              18
       7              53
       1              29
            ...

我想知道哪个任务者的工作时间最长/最少。(这里我们不计算完全有0小时的人。) 起初,我使用这样的SQL查询来实现这个目的:

create table table1 as 
    select tasker_id, sum(working_hours) as sum_hours
    from test.test
    group by tasker_id
    having sum_hours > 0
    order by sum_hours;

select tasker_id, sum_hours
from table1
where sum_hours = (select min(sum_hours) from table1);

这些代码是正确的,我得到了我想要的东西,但我想尝试子查询将这两部分代码放在一起,你知道,不需要构建另一个表,并使用Min()函数来获得最小的工作基于不同ID的列表上的小时数。 我知道Min函数与group by语句一致,我试过这种方式:

select tasker_id, min(sum_hours)
from (select tasker_id, Count(working_hours) as sum_hours
      from test.test 
      group by tasker_ID
      having sum_hours > 0
     ) a;

显然,这是错误的,它说聚合查询需要group by语句。如果我添加" group by tasker_id"在查询的最后一个中,它显示了所有ID,而不是唯一具有最少/最多工作时间的IDS。

那么,有没有人可以帮我解决这个问题? 我知道可能有一些不同的方法来实现这一点,但我想使用Min / Max函数来子查询。

非常感谢!

1 个答案:

答案 0 :(得分:1)

您的第一个代码使用单独的表table1的原因是因为它在第二个查询中使用了两次。如果你把它写成一个查询(没有你的错误),你会发现它并得到一个错误:

--this is wrong!
select tasker_id, sum_hours
from (select tasker_id, sum(working_hours) as sum_hours
      from test.test 
      group by tasker_ID
      having sum_hours > 0) a
where sum_hours = (select min(sum_hours) from a)

你不能再这样使用表a;它不适用于子查询。 你可能会选择丑陋的解决方案并重复查询:

-- this is ugly and slow
select tasker_id, sum_hours
from (select tasker_id, sum(working_hours) as sum_hours
      from test.test 
      group by tasker_ID
      having sum_hours > 0) a
where sum_hours = (select min(sum_hours) from (select tasker_id, sum(working_hours) as sum_hours
      from test.test 
      group by tasker_ID
      having sum_hours > 0) b)

如果您还希望以最长的小时数查看任务程序,那会非常尴尬:

-- this is uglier and slower
select tasker_id, sum_hours
from (select tasker_id, sum(working_hours) as sum_hours
      from test.test 
      group by tasker_ID
      having sum_hours > 0) a
where sum_hours = (select min(sum_hours) from (select tasker_id, sum(working_hours) as sum_hours
      from test.test 
      group by tasker_ID
      having sum_hours > 0) b)
or sum_hours = (select max(sum_hours) from (select tasker_id, sum(working_hours) as sum_hours
      from test.test 
      group by tasker_ID
      having sum_hours > 0) b)

这就是我推荐你的第一个解决方案的原因,只有临时表。为了查询,没有必要使用表来混淆数据库。此外,您应该能够在一次调用数据库时使用这两个以分号分隔的SQL语句。

create temporary table tmphourssum REPLACE as 
select tasker_id, sum(working_hours) as sum_hours
from test.test
group by tasker_id
having sum_hours > 0
order by sum_hours;
select tasker_id, sum_hours
from tmphourssum 
where sum_hours = (select min(sum_hours) from tmphourssum)
or sum_hours = (select max(sum_hours) from tmphourssum)
order by 2 desc