2011-04-13 84 views
5

我正在研究棒球相关网站。我有一个击球阵容的表两个棒球队:在使用MySQL的选择查询中使用CASE,WHEN,THEN,END

+----+----------+--------------+--------+ 
| id | playerId | battingOrder | active | 
+----+----------+--------------+--------+ 

击球顺序为1和20。这对应于下面的逻辑之间的整数:

  1. 击球顺序1-9 —客场球队阵容
  2. 击球顺序10 —客场球队投手
  3. 击球顺序11-19 —首页球队阵容
  4. 击球顺序20 —主队投手

活动区域是一个tinyint 0或1,代表土丘上的投手和盘子上的击球手。

已知的事实:总是会有一个球队的主动投手和对方球队的一个主动投手。

我需要写一个返回一行对应于battingOrder的下一个连击主队球员的查询。

实施例(即该之后发生活性面糊的battingOrder的一个):

  1. 如果battingOrder 13球员是活动的,该查询应在击球顺序返回播放器14
  2. 如果battingOrder 19中的球员处于激活状态,查询应该以击球顺序11返回球员(该阵容循环返回球队的第一个球员)。

我以前从未使用过一个CASE查询,但我想出了以下内容:

SELECT * 
    FROM lineups 
WHERE battingOrder = 
     CASE (
      SELECT battingOrder 
      FROM lineups 
      WHERE battingOrder > 10 AND active = 1 
      LIMIT 1 
     ) 
     WHEN 11 THEN 12 
     WHEN 12 THEN 13 
     WHEN 13 THEN 14 
     WHEN 14 THEN 15 
     WHEN 15 THEN 16 
     WHEN 16 THEN 17 
     WHEN 17 THEN 18 
     WHEN 18 THEN 19 
     WHEN 19 THEN 11 
     END 
LIMIT 1; 

看来工作,但什么边缘情况和/或陷阱我已走进了?这是否有效?我特别感兴趣的是我的问题不使用嵌套查询的解决方案。

回答

7
Select LNext.player As NextPlayer 
From lineups As L 
    Left Join lineups As LNext 
     On LNext.BattingOrder Between 11 And 20 
      And LNext.BattingOrder = Case 
             When L.BattingOrder = 19 Then 11 
             Else L.BattingOrder + 1 
             End 
Where L.battingOrder Between 11 And 20 
    And L.active = 1 

事实上,你可以把它处理无论主客场,像这样:

Select LNext.player As NextPlayer 
From lineups As L 
    Left Join lineups As LNext 
     On LNext.BattingOrder = Case 
            When L.BattingOrder = 19 Then 11 
            When L.BattingOrder = 9 Then 1 
            Else L.BattingOrder + 1 
            End 
Where L.active = 1 
+0

这看起来不正确。你为什么在看id列?它应该是battingOrder列。 – Stephen 2011-04-13 22:50:30

+0

@Stephen - 是的。这是一个错字。固定。 – Thomas 2011-04-13 22:55:28

+0

好吧,我用你的查询逐字逐句,没有结果。我有一名玩家在击球顺序排名第19位处于激活状态,但是您的查询都没有返回任何结果。 – Stephen 2011-04-13 22:57:56