Подсчитать «соотношение?» для выигрышей и проигрышей

#sql

#sql

Вопрос:

Я уже заставил это работать, но это действительно плохой подход, и мне нужна помощь с факторизацией моего запроса.

 SELECT `GameDate`,
   COUNT(CASE
           WHEN `P1Outcome`= 'win' AND  P2Param = 'a' THEN 1 
         END) AS a_win,
   COUNT(CASE
           WHEN `P1Outcome`= 'loss' AND  P2Param = 'a' THEN 1 
         END) AS a_loss,
   COUNT(CASE
           WHEN `P1Outcome`= 'win' AND  P2Param = 'b' THEN 1
         END) AS b_win,
   COUNT(CASE
           WHEN `P1Outcome`= 'loss' AND  P2Param = 'b' THEN 1
         END) AS b_loss
    FROM games 
    WHERE `P2Param` IN ( 'a', 'b', 'c' ) 
    GROUP BY GameDate
  

Это даст мне запрос, который я могу использовать в своем php-приложении, но я хотел бы отказаться от необходимости выполнять фактическое вычисление соотношения в php и получать его напрямую с помощью SQL.

Итак, в основном то, что я пытался сделать, это что-то похожее на это:

    COUNT(CASE
           WHEN `P1Outcome`= 'win' AND  P2Param = 'a' THEN 1 Else -1
         END) AS a_ratio,
  

Но, как и я, новичок, я не могу понять, как я могу заставить это работать.

РЕДАКТИРОВАТЬ: Извините, что не объяснил мои пожелания более подробно, вот в чем дело. Я создаю компонент статистики, и мне нужно получить соотношение за определенный период времени, чтобы отобразить его в виде графика. Итак, требуются следующие действия:

GameDate (1,2,3,4 … дней назад) Соотношение для игрока, основанное на разных параметрах (в данном случае картах)

Итак, вкратце, это то, что я получил на данный момент:

 GameDate      a_win      a_loss    b_win      b_loss 
2011/04/25     x          x         x           x
2011/04/23     x          x         x           x
....
  

Итак, все работает отлично, но я хотел бы, чтобы фактический расчет соотношения был выполнен в SQL, потому что на данный момент мне нужно сделать это, например, на php $ratio = $q[a_win]-$q[a_loss] и из-за того, что у меня много разных параметров, мой запрос примерно вдвое больше, потому что мне нужно получить как выигрыш, так и проигрыш, а не просто соотношение, как я хочу в первую очередь.

Комментарии:

1. Какое фактическое вычисление соотношения вы пытаетесь выполнить (в настоящее время в PHP)?

2. Извините за отсутствие подробностей, и я обновил вопрос, чтобы было легче понять, в чем проблема.

3. @Jakub: P1Outcome отличается.

4. @eggyal Ах да, вы правы. Удаляю комментарий, поскольку он был явно неправильным.

Ответ №1:

 SELECT `GameDate`,
   SUM(CASE `P2Param`
         WHEN 'a' THEN CASE P1Outcome WHEN 'win' THEN 1 ELSE -1 END
         ELSE 0
       END) AS a_ratio,
   SUM(CASE `P2Param`
         WHEN 'b' THEN CASE P1Outcome WHEN 'win' THEN 1 ELSE -1 END
         ELSE 0
       END) AS b_ratio
FROM games
WHERE `P2Param` IN ( 'a', 'b', 'c' ) 
GROUP BY GameDate
  

Комментарии:

1. Другой парень пытается использовать COUNT как SUM. Вы должны были сразу же проголосовать против: D

2. @Jakub: Подождите, был другой, где «соотношение» вычислялось как разница между отдельными … э-э… Я думаю, подсчитывает (не уверен).

3. @Andriy_M Я не уверен, о чем вы спрашиваете сейчас? Функции группировки SQL?

4. @Jakub: Я говорил о другом ответе, который казался правильным, только в нем результаты вычислялись по-другому. Похоже, что это было удалено. ОБНОВЛЕНИЕ: Нет, оно было заменено другим решением. (Это eggyal ‘s.)

5. Я понимаю, да. Интересно, что он также начал с использования COUNT как SUM 🙂

Ответ №2:

Что очень важно, COUNT просто возвращает количество строк независимо от того, что вы считаете, если вы не используете COUNT(DISTINCT ...) , который, в свою очередь, возвращает количество различных значений. Чтобы суммировать некоторые значения, которые вы производите для каждой строки, используйте SUM(...) . Убедитесь, что происходит в вашей СУБД, когда выражение в SUM() функции принимает значение NULL — некоторые базы данных просто возвращают всю СУММУ NULL .

Чтобы получить соотношение любого вида данных, вы можете сделать:

 select _date_, (SUM(case when _your_test_ then 1 else 0 end) / count(1)) as ratio
from _yout_table_
group by _date_
  

И если вы просто хотите вычислить сумму некоторых значений:

 select _date_, SUM(case when _your_test_ then 1 else 0 end) as number_of_something
from _yout_table_
group by _date_
  

Комментарии:

1. Спасибо за ваш ответ, дело в том, что при делении на «/count(1))» это приведет к числу с плавающей запятой, например (0,1523). Мне просто нужен int b / c, у меня есть только целые числа, такие как win = 2 и loss = 5. Разве в любом случае не хотелось бы сохранить каждое количество в переменной и в любом случае сформировать из них сумму?

2. Обычно соотношение понимается как пропорция чего-либо ко всем подобным some selected games/all games . Если вы просто хотите подсчитать выигрыши и проигрыши, просто не делите на, COUNT(1) поскольку это используется для выражения количества всех игр .

3. Вы можете выполнить несколько функций SUM в одном вызове, например SELECT SUM(xxx), SUM(yyy), SUM(xxx)-SUM(yyy), SUM(xxx yyy) . Таким образом, вы можете хранить свои суммы и вычисленные значения в возвращаемых столбцах (не путать с переменными).

Ответ №3:

Как насчет:

   SELECT COUNT(id), P1Outcome, P2Param
    FROM games
GROUP BY P2Param, P1Outcome
  

Он вернет вам результирующий набор из 3 столбцов:

  • подсчитанные значения для параметра и результата
  • результат
  • параметр

На мой взгляд, с этим вы можете сделать больше.

Комментарии:

1. Спасибо за ваш ответ, но это не то, что мне нужно, извините за отсутствие подробностей, и я обновил вопрос, чтобы было легче понять, в чем проблема.

Ответ №4:

 SELECT GameDate, P2Param, SUM(CASE WHEN P1Outcome = 'win' THEN 1 ELSE -1 END) AS ratio
    FROM games
    GROUP BY GameDate, P2Param