SQL Server Union All位于2个表上,除

SQL Server Union All位于2个表上,除,sql,sql-server,Sql,Sql Server,我有两个表和挑战。黑客创建的挑战存储在具有黑客id的挑战表中 黑客:黑客id是黑客的id,name是黑客的名字 挑战:挑战id是挑战的id,黑客id是创建挑战的学生的id。 如果有多个黑客创建了相同数量的挑战,并且计数小于创建的最大挑战数,那么我必须将这些黑客从结果中排除 我想用集合论的概念来解决这个问题,我想先用UNION ALL来计算相等的挑战数,然后用减号将其从主表中排除 以下是我尝试过的: SELECT H.name, C.Hacker_id, count(C.challenge_id)

我有两个表和挑战。黑客创建的挑战存储在具有黑客id的挑战表中

黑客:黑客id是黑客的id,name是黑客的名字 挑战:挑战id是挑战的id,黑客id是创建挑战的学生的id。 如果有多个黑客创建了相同数量的挑战,并且计数小于创建的最大挑战数,那么我必须将这些黑客从结果中排除

我想用集合论的概念来解决这个问题,我想先用UNION ALL来计算相等的挑战数,然后用减号将其从主表中排除

以下是我尝试过的:

SELECT H.name, C.Hacker_id, count(C.challenge_id) AS total_cnt
FROM Hackers H INNER JOIN Challenges C 
ON H.Hacker_id= C.hacker ID
GROUP BY C.hacker_id, H.name

Except 

Select * FROM
(
   (SELECT H2.name, C2.Hacker_id, count(C2.challenge_id) AS total_cnt2
   FROM Hackers H2 INNER JOIN Challenges C2 
   ON H2.Hacker_id= C2.hacker ID
   where total_cnt2!= max(count(C.challenge_id))
   GROUP BY C2.hacker_id, H2.name) t1

 UNION ALL 

   (SELECT H.name, C.Hacker_id, count(C.challenge_id) AS total_cnt3
   FROM Hackers H INNER JOIN Challenges C 
   ON H.Hacker_id= C.hacker ID
   where total_cnt3!= max(count(C.challenge_id))
   GROUP BY C.hacker_id, H.name) t2
)
/* I know this is not correct but I want only where count of challenge is same*/
WHERE t1. total_cnt2= t2. total_cnt3
;
加入后的示例输入为:

我想要这张精确的第一张表,除了挑战计数,它等于罗斯的计数4和弗兰克的计数4


这个问题来自Hackerrank挑战之一,这是一个相当有趣的挑战

我不确定在这种特定情况下使用EXCEPT是否真的能为您带来任何好处,至少在我能解决的范围内没有,因为您可以在不使用EXCEPT的情况下将下面的EXISTS see脚本更改为not EXISTS,但您的结果可能会有所不同

下面是一个SQL,它除了满足以下要求外,还使用:

SELECT hacker_ID, [Name], total_cnt FROM 
(
    SELECT H.[Name], C.Hacker_id, COUNT(C.challenge_id) AS total_cnt
    FROM Hackers H INNER JOIN Challenges C 
    ON H.Hacker_id = C.hacker_ID
    GROUP BY C.hacker_id, H.[Name]
) t1

EXCEPT

SELECT hacker_ID, [Name], total_cnt FROM 
(
    SELECT H.[Name], C.Hacker_id, COUNT(C.challenge_id) AS total_cnt
    FROM Hackers H INNER JOIN Challenges C 
    ON H.Hacker_id = C.hacker_ID
    GROUP BY C.hacker_id, H.[Name]
) t2
WHERE EXISTS (SELECT 1 FROM (SELECT H2.[Name], C2.Hacker_ID, COUNT(C2.challenge_id) AS total_cnt
                             FROM Hackers H2 INNER JOIN Challenges C2 
                             ON H2.Hacker_id = C2.hacker_ID
                             GROUP BY C2.hacker_id, H2.[Name]) T3 WHERE T2.Hacker_ID <> T3.Hacker_ID AND T2.total_cnt = T3.total_cnt
                             AND T3.total_cnt < (SELECT MAX(total_cnt) FROM (SELECT COUNT(*) AS total_cnt 
                                                                    FROM Hackers H3 INNER JOIN Challenges C3 
                                                                    ON H3.Hacker_id = C3.hacker_ID
                                                                    GROUP BY C3.hacker_id, H3.[Name]) T4))
ORDER BY total_cnt DESC, hacker_id 

在其他用户提供的其他解决方案中,我找到了以下最简洁的答案:

在MS SQL Server上,减号被称为除:谢谢!我用普通的方法解决了这个问题,但我想用集合论的方法,因为我觉得这样做很有趣!
SELECT H.name, C.Hacker_id, count(C.challenge_id) AS total_cnt
FROM Hackers H INNER JOIN Challenges C 
ON H.Hacker_id= C.hacker ID
GROUP BY C.hacker_id, H.name

Except 

Select * FROM
(
   (SELECT H2.name, C2.Hacker_id, count(C2.challenge_id) AS total_cnt2
   FROM Hackers H2 INNER JOIN Challenges C2 
   ON H2.Hacker_id= C2.hacker ID
   where total_cnt2!= max(count(C.challenge_id))
   GROUP BY C2.hacker_id, H2.name) t1

 UNION ALL 

   (SELECT H.name, C.Hacker_id, count(C.challenge_id) AS total_cnt3
   FROM Hackers H INNER JOIN Challenges C 
   ON H.Hacker_id= C.hacker ID
   where total_cnt3!= max(count(C.challenge_id))
   GROUP BY C.hacker_id, H.name) t2
)
/* I know this is not correct but I want only where count of challenge is same*/
WHERE t1. total_cnt2= t2. total_cnt3
;
SELECT hacker_ID, [Name], total_cnt FROM 
(
    SELECT H.[Name], C.Hacker_id, COUNT(C.challenge_id) AS total_cnt
    FROM Hackers H INNER JOIN Challenges C 
    ON H.Hacker_id = C.hacker_ID
    GROUP BY C.hacker_id, H.[Name]
) t1

EXCEPT

SELECT hacker_ID, [Name], total_cnt FROM 
(
    SELECT H.[Name], C.Hacker_id, COUNT(C.challenge_id) AS total_cnt
    FROM Hackers H INNER JOIN Challenges C 
    ON H.Hacker_id = C.hacker_ID
    GROUP BY C.hacker_id, H.[Name]
) t2
WHERE EXISTS (SELECT 1 FROM (SELECT H2.[Name], C2.Hacker_ID, COUNT(C2.challenge_id) AS total_cnt
                             FROM Hackers H2 INNER JOIN Challenges C2 
                             ON H2.Hacker_id = C2.hacker_ID
                             GROUP BY C2.hacker_id, H2.[Name]) T3 WHERE T2.Hacker_ID <> T3.Hacker_ID AND T2.total_cnt = T3.total_cnt
                             AND T3.total_cnt < (SELECT MAX(total_cnt) FROM (SELECT COUNT(*) AS total_cnt 
                                                                    FROM Hackers H3 INNER JOIN Challenges C3 
                                                                    ON H3.Hacker_id = C3.hacker_ID
                                                                    GROUP BY C3.hacker_id, H3.[Name]) T4))
ORDER BY total_cnt DESC, hacker_id