基本的SQL查询

时间:2016-01-09 01:04:39

标签: mysql sql sql-server ms-access

下面显示的是SQL数据库和查询我在创建时有点困惑。我只是不确定如何指定结果需要显示已经参加过两场以上比赛的人。

这是我目前的查询:

SELECT playerno
FROM PLAYERS, MATCHES
WHERE PLAYERS.playerno = MATCHES.playerno
AND town = ‘Manchester’;

您将获得以下网球数据库。

PLAYERS (playerno, name, leagueno, year_of_birth, town, street, year_joined, postcode)
TEAMS (teamno, playerno, division)
MATCHES ( matchno, teamno, playerno, sets_won, sets_lost)
PENALTIES (paymentno, playerno, pendate, amount)

Q)查找出现在两场以上比赛中的球员数量 并住在'曼彻斯特'

2 个答案:

答案 0 :(得分:0)

使用'group by'和'having'。

e.g,

SELECT 
    playerno
FROM 
    PLAYERS,
    MATCHES
WHERE 
    PLAYERS.playerno = MATCHES.playerno
    AND town = ‘Manchester’
GROUP BY
    playerno
HAVING
    COUNT(*) >= 2;

答案 1 :(得分:0)

您可以使用几种方法。

一种方法是使用聚合函数和GROUP BY子句来“折叠”具有相同值的行。我们假设如果该播放器的matches表中至少有三行,我们将确定一个播放器在两个以上的匹配项中。

(另外,抛弃连接操作的旧式逗号语法,改为使用JOIN关键字。)

当前查询:

SELECT p.playerno
  FROM PLAYERS p
  JOIN MATCHES m 
    ON m.playerno = p.playerno
 WHERE p.town = 'Manchester'

添加GROUP BY子句以折叠playerno具有相同值的行。

SELECT p.playerno
     , COUNT(1)
  FROM PLAYERS p
  JOIN MATCHES m 
    ON m.playerno = p.playerno
 WHERE p.town = 'Manchester'
 GROUP BY p.playerno
 ORDER BY p.playerno  

ORDER BY并非绝对必要,但它使返回的结果更具确定性。 (如果没有ORDER BY子句,MySQL可以按照它选择的顺序自由返回行。)

下一个技巧是在COUNT(1)子句中引用聚合函数(HAVING)的结果。这不能进入WHERE子句,因为在访问行时会评估WHERE子句中的谓词。我们希望在访问行之后应用谓词,并确定聚合的结果。

SELECT p.playerno
  FROM PLAYERS p
  JOIN MATCHES m 
    ON m.playerno = p.playerno
 WHERE p.town = 'Manchester'
 GROUP BY p.playerno 
HAVING COUNT(1) > 2
ORDER BY p.playerno

这假设同一玩家的matchno值不重复。也就是说,不会有任何两行具有相同的元组值(playerno,matchno)

如果我们没有这种保证,但我们保证matchno非空(至少在我们想要考虑的行上)...来计算matchno的唯一值,我们可以用COUNT(1)替换汇总COUNT(DISTINCT m.matchno)

这只是一种方法的例子。还有其他几个......

另一种方法是使用唯一列(或列集),不等式比较以及对matches表的多个引用。并再次假设我们只想考虑给定计数器中matchno的唯一值...

我们可以使用连接操作,将返回的行限制为matches中具有matchno值较低的播放器中另一行的那些行。

SELECT p.playerno
  FROM players p
  JOIN matches m1  ON m1.playerno = p.playerno
  JOIN matches m2  ON m2.playerno = p.playerno AND m2.matchno > m1.matchno 
  JOIN matches m3  ON m3.playerno = p.playerno AND m3.matchno > m2.matchno 
 WHERE p.town = 'Manchester'    
GROUP BY p.playerno
ORDER BY p.playerno

另一种方法是使用EXISTS谓词来执行类似的检查。在玩家的匹配中是否存在一行,其中匹配中的另一行对于具有更高matchno值的同一玩家,...

这样的事情:

SELECT p.playerno
  FROM players p
 WHERE p.town = 'Manchester'
   AND EXISTS
       ( SELECT 1 
           FROM matches m1
          WHERE m1.playerno = p.playerno
            AND EXISTS 
                ( SELECT 1 
                    FROM matches m2
                   WHERE m2.player_no = m1.playerno
                     AND m2.matchno   > m1.matchno
                     AND EXISTS 
                         ( SELECT 1
                             FROM matches m3
                            WHERE m3.playerno = m2.playerno
                              AND m3.matchno  > m2.matchno
                         )
                ) 
       )
ORDER BY p.playerno