INSERT or UPDATE mysql, php

107
23 августа 2019, 15:20

Не знаю как реализовать данную задачу(таблица cron_planning_figure):

Имеется вот такой вид таблицы. Я написал скрипт который будет делать запрос(собирать все то что вы видите на скриншоте) а затем он должен делать INSERT в таблицу либо же UPDATE.

Скрипт будет запускаться кроном несколько раз в день. Работать будет все следующим образом: Это статистика людей за текущий месяц(в моем случае за январь, день и время мне не важно, главное чтобы был год и месяц, но для удобства я храню время в timestamp).

Апдейт будет в том случае. когда поле fact меняется, а оно будет меняться постоянно, поле work_days, каждый день будет +1, ну и поле month_year(это простой timestamp).

А инсерт будет делаться только в двух случаях, если начался новый месяц и если появился новый пользователь( в нашем случае их всего 7, завтра может быть уже 8). Когда наступит февраль то там появится опять 7 записей(может больше, если кто-то из новеньких будет).

Смотрел в сторону INSERT ODKU - не особо мне подходит. Может как-то с помощью пыха такое реализовать? Спасибо за внимание. немного запутанная задача.тяжело объяснить

Подытожим:

INSERT - наступает новый месяц. Появилась новая строка в таблице(должна вставиться новая строка с новым user_id)

UPDATE - при изменение полей (plan,fact,work_days)

Спасибо за внимание!

Выкладываю код на всякий случай, были попытки что-то сделать, но пока не пойму логику(знаю прекрасно что лучше mysqli или pdo, но сейчас не об этом):

include_once (dirname(__DIR__).'/application/config.php');
$values = array();
$array = array();
$sql_request = "
      SELECT 
        r.userId as user_id,
        CURRENT_TIMESTAMP as month_year,
        (SELECT spf.plan_value FROM settings_planning_figure AS spf WHERE DATE_FORMAT(spf.month,'%Y-%m') = '2019-01' AND spf.role = u.rules) AS plan,
        CAST(AVG(
          CASE
            WHEN r.reject_date IS NULL AND DATE_FORMAT(r.date_add, '%Y-%m') = '2019-01' THEN TIMESTAMPDIFF(MINUTE,r.date_add,r.approve_date)
            WHEN r.approve_date IS NULL AND DATE_FORMAT(r.date_add, '%Y-%m') = '2019-01' THEN TIMESTAMPDIFF(MINUTE,r.date_add,r.reject_date)
          END) AS DECIMAL(10,1)) AS fact,
        (SELECT COUNT(*)
          FROM (
            SELECT *
            FROM log_user_activity AS lua
            WHERE lua.user_id IN
               (SELECT u.id FROM users AS u WHERE u.rules IN ('21','25','29') AND 
                  u.block_status = 0 AND 
                  u.id != 120
               ) AND
                DATE_FORMAT(lua.action_date, '%Y-%m') = '2019-01'
                GROUP BY DATE_FORMAT(lua.action_date, '%Y-%m-%d'), lua.user_id
               ) AS count_days
         WHERE count_days.user_id = u.id
         GROUP BY userId) AS work_days
      FROM request AS r
      INNER JOIN users AS u ON u.id = r.userId
      WHERE r.userId IN(
              SELECT u.id
              FROM users AS u
              WHERE u.rules IN ('21','25','29') AND u.block_status = 0 AND u.id != 120) AND
              (CAST(r.date_add AS date) = CAST(r.reject_date AS date) OR CAST(r.date_add AS date) = CAST(r.approve_date AS date))
      GROUP BY r.userId";
$sql_cpf = "SELECT * 
            FROM cron_planning_figure as cpf 
            WHERE date_format(cpf.month_year,'%Y-%m') = date_format(CURRENT_DATE,'%Y-%m')";
$query_cpf  = mysql_query($sql_cpf,$connect_db);
while($result = mysql_fetch_assoc($query_cpf)){
    $array['date'] = $result['month_year'];
    $array['user_id'][] = $result['user_id'];
}
$query = mysql_query($sql_request,$connect_db);
while($result = mysql_fetch_assoc($query)) {
    $values['string'][] = "('$result[user_id]', '$result[month_year]',
                  '$result[plan]',    '$result[fact]', '$result[work_days]'
                 )";
    $values['user_id'][] = $result['user_id'];
}
if(date('Y-m',strtotime($array['date'])) == date('Y-m') || !empty(array_diff($values['user_id'],$array['user_id']))){
    $sql = "UPDATE";
}
else
{
    $sql = "INSERT INTO cron_planning_figure (user_id, month_year, plan, fact, work_days)
            VALUES "  .implode(",",$values['string']);
}
mysql_query($sql, $connect_db);
Answer 1

Как всегда, проблема здесь в неверном подходе.

Начиная работать с БД, большинство людей не понимают её динамического характера, и по привычке относятся к ней, как к классному журналу с оценками. В котором единственный способ поменять информацию - это соскрести лезвием и ластиком одну оценку и вписать другую.

База данных работает по-другому.

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

в данном случае надо две таблицы

  • в первой хранится юзера, дата и план. одна строка за день.
  • во второй хранится юзер, дата и факт. за каждый день столько строк, сколько записей о фактах.

дальше, в запросе SELECT мы применяем магическую функцию sum() для подсчета факта за каждый день, сгруппировав для этого запрос по юзеру и дате. Количество рабочих дней можно при этом посчитать в пхп, а можно отдельным запросом.

Несмотря на то, что это все кажется запредельно сложным, на самом деле это все примитивные запросы, уровня таблицы умножения. их надо освоить и начать применять БД по назначению.

READ ALSO
Как наследовать шаблонный класс?

Как наследовать шаблонный класс?

Как создать обычный (не шаблонный класс), который наследовал бы шаблонный без явного определения типа? Хочу сделать подобие итератора,

136
Подключение к веб-серверу из глобальной сети

Подключение к веб-серверу из глобальной сети

Я пишу свой веб-сервер на C++Планируется подключаться к нему с браузера, а он в ответ должен выдавать html-странички

119
Как это работает? Пример TDLib с шаблонами на C++

Как это работает? Пример TDLib с шаблонами на C++

Не могу до конца сообразить как работает данная конструкция в примере использования библиотеки TDLibсам пример

139
Рекурсия и фишки

Рекурсия и фишки

Есть задача о фишках, необходимо ее решить рекурсией, вот условие:

138