#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