Вот один из способов сделать это.
Наличие примеров данных в вопросе облегчает проверку решения. Пожалуйста, включите его в следующий раз.
CTE
- это простая агрегация для получения количества вызовов, поданных каждым хакером.
In CTE2
MAX
дает глобальную максимальную частоту. HackerCountOfSameFreq
- это число хакеров с одинаковой частотой.
Final WHERE
удаляет группы хакеров, состоящие из более чем одного хакера, но покидает группу с максимальной частотой.
Пример данных
DECLARE @Hackers TABLE (hacker_id int, name varchar(50));
INSERT INTO @Hackers VALUES
(1, 'john'),
(2, 'tom'),
(3, 'anna'),
(4, 'mary'),
(5, 'steve');
DECLARE @Challenges TABLE (challenge_id int, hacker_id int);
INSERT INTO @Challenges VALUES
(1 , 1),
(2 , 1),
(3 , 1),
(4 , 2),
(5 , 2),
(6 , 2),
(7 , 2),
(8 , 3),
(9 , 3),
(10, 3),
(11, 4),
(12, 4),
(13, 4),
(14, 4),
(15, 5),
(16, 5);
Запрос
WITH
CTE
AS
(
SELECT hacker_id, COUNT(*) AS FreqHacker
FROM @Challenges
GROUP BY hacker_id
)
,CTE2
AS
(
SELECT
hacker_id
,FreqHacker
,COUNT(*) OVER (PARTITION BY FreqHacker) AS HackerCountOfSameFreq
,MAX(FreqHacker) OVER () AS GlobalMaxFreq
FROM CTE
)
SELECT
CTE2.hacker_id
,CTE2.FreqHacker
,H.Name
FROM
CTE2
INNER JOIN @Hackers AS H ON H.hacker_id = CTE2.hacker_id
WHERE
HackerCountOfSameFreq = 1
OR FreqHacker = GlobalMaxFreq
ORDER BY
CTE2.hacker_id
;
Результат
+-----------+------------+-------+
| hacker_id | FreqHacker | Name |
+-----------+------------+-------+
| 2 | 4 | tom |
+-----------+------------+-------+
| 4 | 4 | mary |
+-----------+------------+-------+
| 5 | 2 | steve |
+-----------+------------+-------+
Ваш запрос также дает правильный результат (по крайней мере, с этими примерами данных), как только синтаксис исправлен.
Я разделил его на CTE, оставив большую часть ваших логик c как:
WITH
d
AS
(
SELECT hacker_id, COUNT(challenge_id) AS FreqHacker
FROM @Challenges
GROUP BY hacker_id
)
,dd
AS
(
SELECT d.FreqHacker, COUNT(d.FreqHacker) as FreqOfFreq
FROM d
GROUP BY d.FreqHacker
)
,d3
AS
(
SELECT
h.hacker_id,
h.name,
COUNT(c.challenge_id) AS ChalCountPerHead
FROM
@hackers h
JOIN @challenges c ON h.hacker_id = c.hacker_id
GROUP BY h.hacker_id, h.name
)
,d4
AS
(
SELECT *
FROM
d3
LEFT JOIN dd ON dd.FreqHacker = ChalCountPerHead
)
SELECT *
FROM d4
WHERE
ChalCountPerHead = (SELECT MAX(d.FreqHacker) from d)
OR FreqOfFreq = 1
ORDER BY hacker_id
;