Learning SQL … Is there a better way to write this?

[亡魂溺海] 提交于 2019-12-11 13:18:24

问题


This is the question I'm trying to answer...

What are the team names of all teams who had one and only one player appear in 145 or more games?

Here is my solution.

SELECT name
  From Teams
 WHERE teamID IN (SELECT original.teamID
                    FROM Appearances original
                   WHERE teamID Not In (SELECT one.teamID
                                         FROM Appearances one, Appearances two
                                        Where (one.teamID = two.teamID) 
                                          AND (one.playerID <> two.playerID) 
                                          AND (one.GS > 144) AND (two.GS > 144)));

This works, but I'm wondering if there is a cleaner/more efficient way to write this. I'm using Derby as my dbms.


回答1:


I'm not sure if your query does work. I would would expect it to be more like this:

SELECT name
  FROM Teams
 WHERE teamID IN 
       ( SELECT one.teamID
           FROM Appearances one
          WHERE (one.GS > 144)
                AND one.teamID NOT IN 
                ( SELECT two.teamID
                    FROM Appearances two
                   WHERE (one.teamID = two.teamID)
                         AND (one.playerID <> two.playerID) 
                         AND (two.GS > 144) ) );



回答2:


I THINK this is what you want. Assuming GS is some sort of unique identifier for the game. And you are looking for teams that have played in a count of equal to or greater than 145 games. Also, I'm not sure if there's syntax mistakes, I wrote this in notepad and I'm about to head to bed.

Basically the inner SELECT finds all "Appearances" where only 1 player played, grouping by GS (games?) and teamId. We should get back ALL appearances with only 1 appearance (if that makes sense). In theory, if there are 200 games, but 146 had only 1 appearance, only 146 results would be returned.

Then the outer SELECT does a join on that result and finds where the count is greater than or equal to 145. Apologies if you already understand that, but based on your title, it sounds like you're new to SQL.

SELECT
    t.name
FROM
    Teams t
JOIN
(
    SELECT
        a.teamId
    FROM
        Appearances a
    GROUP BY
        a.GS
        , a.teamId
    HAVING
        COUNT(a.GS) = 1
) p1 ON t.teamId = p1.teamId
GROUP BY
    t.name
HAVING
    COUNT(t.name) >= 145

Cheers. Let me know if it works or doesn't.




回答3:


Try:

select max(t.name) team_name
from teams t
join appearances a on t.team_id = a.team_id and a.GS > 144
group by t.team_id
having count(distinct a.playerID)=1


来源:https://stackoverflow.com/questions/9629100/learning-sql-is-there-a-better-way-to-write-this

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!