2011-04-13 16 views
5

Estoy trabajando en un sitio web relacionado con el béisbol. Tengo una tabla con una formación de bateo para los dos equipos de béisbol:Usando CASE, WHEN, THEN, END en una consulta de selección con MySQL

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

orden de bateo es un entero entre 1 y 20. Esto se corresponde con la siguiente lógica:

  1. bateo Solicitar 1-9 — lejos Formación del equipo de
  2. bateo Orden de 10 — de equipo visitante Pitcher
  3. bateo Solicitar 11-19 — equipo Local Formación
  4. Bateo Orden 20 — Equipo Local Pitcher

El campo activo es un tinyint 0 o 1, que representa el lanzador en el montículo y el bateador en el plato.

Hecho conocido: Siempre habrá un lanzador activo de un equipo y un bateador activo del equipo contrario.

Tengo que escribir una consulta que devuelve una fila para un jugador de equipo local que corresponde a la siguiente bateador en el battingOrder. (La que que se produce después de battingOrder de bateo activo)

Ejemplo:

  1. Si el jugador en battingOrder 13 está activo, la consulta debe devolver el jugador con el fin de bateo 14.
  2. Si el jugador en BattingOrder 19 está activo, la consulta debe devolver al jugador en orden de bateo 11 (la alineación vuelve al primer jugador del equipo).

nunca he utilizado una consulta CASO antes, pero se me ocurrió lo siguiente:

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; 

Parece que funciona, pero lo borde casos y/o trampas han entré en? ¿Es esto eficiente? Estoy particularmente interesado en una solución a mi problema que no utiliza una consulta anidada.

Respuesta

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 

De hecho, usted podría hacer que manejar tanto en casa como fuera de esta manera:

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

Esto no parece estar bien. ¿Por qué estás mirando la columna de identificación? Debería ser la columna battingOrder. – Stephen

+0

@Stephen - Sí. Eso es un error tipográfico Fijo. – Thomas

+0

Bueno, he utilizado su consulta textualmente sin ningún resultado. Tengo un jugador en la posición de orden de bateo 19 como activo, pero ambas consultas no arrojan ningún resultado. – Stephen

Cuestiones relacionadas