繁体   English   中英

一对多关系的左联接上具有聚合功能的SQL查询

[英]SQL Query with Aggregate function on Left Join of One-to-Many Relationship

我有一对多关系,其中每个用户都有许多任务,这些任务按难度进行评估。 我想查询一个列表,该列表显示每个用户一次及其最困难的任务。

用户表:user_id,用户名

任务表:user_id,task_id,任务名称,难度

我已经尝试过查询

SELECT u.user_id, u.username, t.task_id, t.taskname, MAX(t.difficulty)
FROM users u
LEFT JOIN tasks t ON u.user_id = t.user_id
GROUP BY u.user_id

但是,运行此命令时,我收到not in GROUP BY clause错误。

我认为您正在寻找这样的东西

SELECT u.user_id, u.username, t.task_id, t.taskname,t.difficuilty
FROM users u LEFT JOIN tasks t ON u.user_id = t.user_id
INNER JOIN 
(
 SELECT user_Id,Max(difficuilty) D FROM tasks GROUP BY user_id
)Temp ON Temp.user_id = u.user_id ANDTemp.D = t.difficuilty
GO

假设一个用户没有两个任务具有相同的最大难度,则可以执行以下操作。 虽然,这不是很出色。 它在较小的数据集上可以正常工作,但是如果您的数据集非常大,则应重新设计。 希望它能使您指出正确的方向。

declare @users table (user_id int, username varchar(10))
declare @tasks table (task_id int, user_id int, taskname varchar(24), difficulty int)

insert into @users values
(1, 'John'),
(2, 'Sally'),
(3, 'Sam')

insert into @tasks values
(1, 1, 'prepare grocery list', 1),
(2, 1, 'do shopping', 2),
(3, 1, 'cook food', 3),
(4, 2, 'do shopping', 2),
(5, 2, 'prepare grocery list', 1),
(6, 3, 'cook food', 3)

select u.user_id, u.username, t.task_id, t.taskname, t.difficulty
from   @users u
       left join @tasks t on u.user_id = t.user_id
where  t.difficulty = (
         select max(x.difficulty)
         from   @tasks x
         where  t.user_id = x.user_id
       )

这样会更高效:

select u.user_id, u.username, t.task_id, t.taskname, t.difficulty
from   @users u
       left join @tasks t on u.user_id = t.user_id
       inner join (
         select x.user_id, max(x.difficulty) as max_difficulty
         from   @tasks x
         group by x.user_id
       ) as y on t.user_id = y.user_id and t.difficulty = y.max_difficulty

这两个查询均返回以下数据集:

user_id     username   task_id     taskname                 difficulty
----------- ---------- ----------- ------------------------ -----------
1           John       3           cook food                3
2           Sally      4           do shopping              2
3           Sam        6           cook food                3

如果一个用户有两个具有相同难度的最大任务,则查询将包括该用户的两行。

尽管显示此SQL的查询计划表明第二查询的费用几乎是第一查询的两倍。 where子句中使用max()似乎比在from子句中放置max()更有效。 我会尝试两种方式处理您的真实数据,并查看适合您的查询计划/费用。

尝试

    SELECT u.user_id, u.username, t.task_id, t.taskname, m.difficulty
      FROM tasks t
RIGHT JOIN (SELECT user_id, 
                   MAX(difficulty) as difficulty
              FROM tasks
          GROUP BY user_id) m ON t.user_id = m.user_id 
                             AND t.difficulty = m.difficulty
 LEFT JOIN users u ON t.user_id = u.user_id;

暂无
暂无

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

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