我遇到了一些问题。问题有两个表,即黑客和挑战。 这是架构:
Hackers(hacker_id: int, name string)
Challenges(challenge_id: int, hacker_id int)
我正在尝试编写一个查询来打印hacker_id,名称以及每个学生创建的挑战总数。按降序排列挑战总数对结果进行排序。如果多个学生创建了相同数量的挑战,则按hacker_id对结果进行排序。如果多个学生创建了相同数量的挑战且计数小于创建的最大挑战数,则将结果中的学生排除在外。
这是我的问题:
select hackers.hacker_id ,
hackers.name ,
count(challenges.challenge_id) as challenges_created
from
hackers left join challenges
on
hackers.hacker_id = challenges.hacker_id
having
count(challenges_created) >= max(challenges_created)
order by challenges_created desc, hackers.hacker_id asc
输错了! 请告诉我哪里出错了!
示例输入:
Sample Output:
21283 Angela 6
88255 Patrick 5
96196 Lisa 1
答案 0 :(得分:1)
这只是在mysql中解决的疯狂要求。使用CTE(不支持mysql),您可以重用查询:
with tmp as (
select h.hacker_id, h.name, count(1) as challenges_created
from hackers h
left join challenges c on c.hacker_id = h.hacker_id
group by h.hacker_id, h.name
order by challenges_created desc, h.hacker_id asc
), max_challenges_created as (
select max(challenges_created) as challenges_created
from tmp
), count_per_challenges_created as (
select challenges_created, count(1) as c
from tmp
group by challenges_created
)
select *
from tmp
cross join max_challenges_created m
left join count_per_challenges_created c on c.challenges_created = tmp.challenges_created
where tmp.challenges_created = m.challenges_created
or c.c = 1
http://rextester.com/XGYQ11641
在MySQL中,您甚至无法使用临时表,因为您无法在一次查询中多次使用它。所以你必须复制并粘贴相同的查询三次(并希望mysql只使用缓存执行一次):
select *
from (
select h.*, count(1) as challenges_created
from hackers h
left join challenges c on c.hacker_id = h.hacker_id
group by h.hacker_id
order by challenges_created desc, h.hacker_id
) tmp
cross join (
select max(challenges_created) as challenges_created
from (
select h.*, count(1) as challenges_created
from hackers h
left join challenges c on c.hacker_id = h.hacker_id
group by h.hacker_id
order by challenges_created desc, h.hacker_id asc
) tmp
) m
left join (
select challenges_created, count(1) as c
from (
select h.*, count(1) as challenges_created
from hackers h
left join challenges c on c.hacker_id = h.hacker_id
group by h.hacker_id
order by challenges_created desc, h.hacker_id asc
) tmp
group by challenges_created
) c on c.challenges_created = tmp.challenges_created
where tmp.challenges_created = m.challenges_created
or c.c = 1
答案 1 :(得分:1)
尝试开始解决查询的最小部分并继续加入它们。 您可以尝试我的SQL(Oracle)代码
SELECT h.hacker_id,
h.name,
COUNT(c.challenge_id) AS challenge_count
FROM Hackers h
JOIN Challenges c ON c.hacker_id = h.hacker_id
GROUP BY h.hacker_id, h.name
HAVING challenge_count =
(SELECT COUNT(challenge_id) AS count_max
FROM Challenges
GROUP BY hacker_id
ORDER BY count_max DESC limit 1)
OR challenge_count IN
(SELECT DISTINCT c_compare AS c_unique
FROM (SELECT h2.hacker_id,
h2.name,
COUNT(challenge_id) AS c_compare
FROM Hackers h2
JOIN Challenges c ON c.hacker_id = h2.hacker_id
GROUP BY h2.hacker_id, h2.name) counts
GROUP BY c_compare
HAVING COUNT(c_compare) = 1)
ORDER BY challenge_count DESC, h.hacker_id;
答案 2 :(得分:1)
尝试一下,这很简单。...
select
h.hacker_id,
h.name
from hackers h, difficulty d, challenges c, submissions s
where
h.hacker_id=s.hacker_id
and s.challenge_id=c.challenge_id
and d.difficulty_level=c.difficulty_level
and d.score=s.score
group by h.hacker_id, h.name
having count(*)>1
ORDER BY COUNT(*) DESC, h.hacker_id;
答案 3 :(得分:0)
这不是真正的答案,而是你的起点:
http://sqlfiddle.com/#!9/6910c/5
SELECT h.hacker_id ,
h.name ,
COUNT(challenges.challenge_id) as challenges_created
FROM hackers h
LEFT JOIN challenges
ON h.hacker_id = challenges.hacker_id
GROUP BY h.hacker_id
#HAVING challenges_created >= max(challenges_created)
ORDER BY challenges_created desc, h.hacker_id asc
我已经注释了你的HAVING
条款,因为无法理解你想要实现的目标。
解释一下,为什么你期望结果只有3行?为什么应该从结果集中排除Rose
和Frank
?
答案 4 :(得分:0)
在必要的表上使用多个连接时,解决方案很容易。为了清楚起见,我喜欢将结果分组为派生表,但也可以在没有这些派生表的情况下完成。
prod
答案 5 :(得分:0)
select hacker_id, name, tmp.challenges_created
from (
select h.*, count(1) as challenges_created
from hackers h
left join challenges c on c.hacker_id = h.hacker_id
group by h.hacker_id, h.name
order by challenges_created desc, h.hacker_id
) tmp
cross join (
select max(challenges_created) as challenges_created
from (
select h.*, count(1) as challenges_created
from hackers h
left join challenges c on c.hacker_id = h.hacker_id
group by h.hacker_id, h.name
order by challenges_created desc, h.hacker_id asc
) tmp
) m
left join (
select challenges_created, count(1) as c
from (
select h.*, count(1) as challenges_created
from hackers h
left join challenges c on c.hacker_id = h.hacker_id
group by h.hacker_id, h.name
order by challenges_created desc, h.hacker_id asc
) tmp
group by challenges_created
) c on c.challenges_created = tmp.challenges_created
where tmp.challenges_created = m.challenges_created
or c.c = 1
答案 6 :(得分:0)
SELECT a.hacker_id, a.name, b.id
FROM Hackers a
INNER JOIN (SELECT hacker_id, id
FROM (SELECT hacker_id, count(challenge_id) AS id
FROM Challenges
GROUP BY hacker_id) x
WHERE id = 50
UNION ALL
SELECT hacker_id,id
FROM (SELECT hacker_id, count(challenge_id) AS id
FROM Challenges
GROUP BY hacker_id) y
WHERE id IN (SELECT id
FROM (SELECT hacker_id, count(challenge_id) AS id
FROM Challenges
GROUP BY hacker_id) x
GROUP BY id
HAVING count(*) = 1)
) b ON a.hacker_id = b.hacker_id
ORDER BY id DESC, hacker_id
答案 7 :(得分:0)
这是hackerranck.com中的问题,您可以检查它here [link] 在此站点中,您可以通过许多SQL DBMS(oracale,maysql,sqlserver和DB2)传递答案
对于 SQL-SERVER
来说,效果很好with t
as(
Select s.hacker_id ,
s.score,d.Difficulty_level as Difficulty_level,
c.Challenge_id
From submissions s
inner join Challenges c on c.Challenge_id = s.Challenge_id
inner join Difficulty d on d.Difficulty_level = c.Difficulty_level and d.score = s.score
)
Select t.hacker_id, h.name
From t inner join hackers h ON t.hacker_id=h.hacker_id
Where t.score in (Select score from Difficulty)
Group by t.hacker_id,h.name
Having count(t.Challenge_id) > 1
Order by count(t.Challenge_id) desc,t.hacker_id asc
答案 8 :(得分:0)
我已经在SQL Server中完成 我加入了2个不同的选择,第一个使用等级来确定具有等级1的选择,第二个使用重复的选择,因此在联接结果中,我将结果过滤为具有第一个等级或没有重复(cnt = 1)
select s.hacker_id, s.name, s.challenge_created from (
select * ,rank() over (order by challenge_created desc) rn from (
select h.hacker_id, name, count(challenge_id) challenge_created from hackers h
inner join challenges c on h.hacker_id = c.hacker_id
group by h.hacker_id, name) as T) as S
inner join (select A.challenge_created , count(1) cnt from (select h.hacker_id, name, count(challenge_id) challenge_created from hackers h
inner join challenges c on h.hacker_id = c.hacker_id
group by h.hacker_id, name) as A group by A.challenge_created) as O
on s.challenge_created = O.challenge_created
where rn = 1 or O.cnt = 1
order by s.challenge_created desc , hacker_id
答案 9 :(得分:0)
以下查询在mysql中工作正常 对于具有条款条件 我已经包含了计数等于 创建的最大挑战数或 挑战的数量是独一无二的
select c.hacker_id,h.name,count(c.challenge_id) as cnt from
challenges c join hackers h
on c.hacker_id = h.hacker_id
group by c.hacker_id,h.name
having cnt =
(select max(counts) from (select count(challenge_id) as counts from challenges group by hacker_id) as countstable1) or
cnt in (select counts from (select count(challenge_id) as counts from challenges group by hacker_id) as countstable2 group by counts having count(*)=1)
order by cnt desc,c.hacker_id