나는 각 사용자가 난이도로 평가되는 많은 작업을 가지고있는 일대 다 관계를 가지고 있습니다. 가장 어려운 작업과 함께 각 사용자를 한 번씩 보여주는 목록을 쿼리하고 싶습니다.
사용자 테이블 : 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
이것을 실행할 때 오류가 발생합니다.
한 명의 사용자가 동일한 최대 난이도를 가진 두 개의 작업이 없다고 가정하면 다음과 같이 할 수 있습니다. 그러나 이것은 매우 성능이 좋지 않습니다. 작은 데이터 세트에서는 잘 작동하지만 데이터 세트가 매우 큰 경우 다시 디자인해야합니다. 바라건대 그것은 당신이 올바른 방향을 가리 키도록 할 것입니다.
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에 대한 쿼리 계획을 보여 주면 두 번째 쿼리 비용이 첫 번째 쿼리 비용의 거의 두 배에 달한다는 것을 알 수 있습니다. 데 max()
에 where
절은 걸릴 배치보다 더 효율적인 것으로 보인다 max()
에 from
절. 실제 데이터에 대해 두 가지 방법을 모두 시도하고 쿼리 계획 / 비용이 무엇인지 확인합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다