Использование CASE, WHEN, THEN, END в запросе выбора с MySQL - PullRequest
5 голосов
/ 14 апреля 2011

Я работаю над сайтом, связанным с бейсболом. У меня есть стол с составом ватина для двух бейсбольных команд:

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

Порядок ватин представляет собой целое число от 1 до 20. Это соответствует следующей логике:

  1. Порядок ватин 1-9 & mdash; Состав команды гостей
  2. Ватин порядка 10 & mdash; Кувшин в гостях
  3. Порядок ватин 11-19 & mdash; Состав домашней команды
  4. Ватин порядка 20 & mdash; Кувшин домашней команды

Активным полем является tinyint 0 или 1, представляющее кувшин на насыпи и жидкое тесто на тарелке.

Известный факт : Всегда будет один активный кувшин от одной команды и один активный кувшин от противоположной команды.

Мне нужно написать запрос, который возвращает строку для игрока домашней команды, которая соответствует следующему бэттеру в 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;

Кажется, это работает, но в какие крайние случаи и / или ловушки я попал? Это эффективно? Меня особенно интересует решение моей проблемы, которое не использует вложенный запрос.

1 Ответ

7 голосов
/ 14 апреля 2011
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
...