Различные вопросы по PHP и MySQL

85.18K
.
Hat-Trick, Скорее всего, не правильно озвучена задача. 
Дай дамп для теста, и скажи что тебе надо там конкретно получить. 
.
Добавлено: 22.10.2020 / 21:25
Hat-Trick,
select x.* 
    , f.* 
from (
         SELECT `id`, 
            `column1` + `column2` AS `c1`, 
            `column2` + `column3` AS `c2`, 
            `column3` + `column1` AS `c3`
         FROM `table`
) x 
JOIN `table` as `f` 
   ON 
      `f`.`id` = `x`.`id`


Добавлено: 22.10.2020 / 21:26
а вообще надо понять, структуру таб, и что на выхлопе получить.
.
Hat-Trick
# desay (22.10.2020 / 21:13)
Hat-Trick, Скорее всего, не правильно озвучена задача. 
Дай дамп для теста, и скажи что тебе надо там конкретно получить. 
Задача большая, но принцип работы такой
Есть таблица `игроки` c полями `ид`, `защита`, `полузащита`, `нападение`, `отбор`, `пас`, `удар`
Хочется придумать велосипед, чтобы чисто на sql получить позицию игрока. Позиции: защитник, полузащитник, нападающий.
$array['защитник'] = защита + отбор
$array['полузащитник'] = полузащита + пас
$array['нападающий'] = нападение + удар
дальше это в массив, сортируем значения по убыванию, получаем короче позицию на основе того, где сумма навыков самая большая. То есть если отбор+защита больше остальных вариантов, то игрок - защитник.
Ну понятно на PHP уже реализовано это дело. Мне просто хочется покопаться в возможностях SQL.
Я реализовал это так (принцип такой же, только у меня 16 навыков, 16 возможных позиций и пара условий).

SELECT `x`.*, 
(CASE
    WHEN GREATEST(`x`.`защитник`, `x`.`полузащитник`, `x`.`нападающий`) = `защитник` THEN 'защитник'
    WHEN GREATEST(`x`.`защитник`, `x`.`полузащитник`, `x`.`нападающий`) = `полузащитник` THEN 'полузащитник'
    WHEN GREATEST(`x`.`защитник`, `x`.`полузащитник`, `x`.`нападающий`) = `нападающий` THEN 'нападающий'
END) as `позиция`
FROM (SELECT `ид`, 
   (`защита` + `отбор`) AS `защитник`, 
   (`полузащита` + `пас`) AS `полузащитник`, 
   (`нападение` + `удар`) AS `нападающий`
FROM `игроки`
GROUP BY `ид`) as `x` 
LEFT JOIN `игроки` as `f` ON (`f`.`ид` = `x`.`ид`)


В подзапросе получаю сумму полей (навыков) для каждой позиции и такой alias и даю получившемуся результату.
Потом из получившихся сумм навыков выбираю наибольшее значение и сравниваю его со значениями для каждой позиции. Где значение совпадает, то полю `позиция` ставлю это значение.
Для таблицы в 100к строк и весом 60мб запрос выполняется 1-2 секунду. То есть 100к игрокам подбирается лучшая позиция за 1-2 секунды. Это, например, быстрее чем получить список 100к игроков, в цикле while сосчитать для каждого сумму навыков и выбрать лучшую позицию, а потом в поле `позиция` записать 100к раз это значение. Для одного же игрока (в подзапросе ставим WHERE `ид` = $id) запрос в этой же таблице выполняется за 0,002 - 0,003 сек.
.
Кадило крутится, лавэха мутится
# Hat-Trick (22.10.2020 / 23:23)
Для таблицы в 100к строк и весом 60мб запрос выполняется 1-2 секунду. То есть 100к игрокам подбирается лучшая позиция за 1-2 секунды. Это, например, быстрее чем получить список 100к игроков, в цикле w
Ну это ужасно долго на самом деле) А если этот запрос у тебя будет выполняться слишком часто, в каком нить нагруженном месте, то сервер не скажет спасибо тебе уже при 10-20 активных игроках)
Стоит подумать над оптимизацией всего этого дела... Проводить эти расчеты раз в какой-то период или ещё при каких-то условиях или вообще переделать как-то по-другому.
.
Simba, Я на PHP это делаю) Там где идет обновление навыка, если навык повысился на единицу, то пересчитываем позиции игроков и выбираем лучшую, записываем в базу. Короче миллисекунды. Это просто описание задачи простецкое и только ради интереса.
А вообще подзапрос не нужен. Просто вместо того, чтобы сравнивать алиасы из подзапроса, нужно сравнивать сами суммы навыков в GREATEST c суммой навыков для позиции и давать уже это значение. И тогда запрос для всей таблицы в 100к выполняется за 0,002 сек)). Только сам запрос выходит на полторы сотни строк.
.
Hat-Trick
Добавлено: 10.03.2021 / 07:58
Почему в движке повсеместно для хранения времени используется int, а не timestamp или datetime?
Нашёл лишь пару мест где это не так. Даже дата рождения юзера хранится по отдельности (год, месяц, день). Я и сам использую для хранения int и работаю со времени средствами PHP. Но делаю это потому что в движке так сделано и начинал я с этого. То есть выбор неосознанный. Попытался осознать и перебрал кучу материала, но так и не смог выделить какие-либо существенные плюсы для себя в использовании этих форматов. Это я так сильно привык (хотя работал с обоими вариантами) или плюсов действительно мало, а иногда это наоборот только гемор?
.
(\/)____o_O____(\/)
Ну при работе с инт таймстампом математика на стороне пхп, при формате даты, на стороне мускула. Как по мне и то и то норм, дело привычки, кому то проще в бд, кому то в пыхе
.
Зачем нужны float и double если есть decimal?
.
(\/)____o_O____(\/)
Разная точность
.
Hey guys! Finally I'm gonna change status!?
Hat-Trick, decimal, на много медленнее, тогда как во многих случаях достаточно точности float/double.
Всего: 7969