Ответы пользователя по тегу MySQL
  • Как переделать этот запрос с применением JOIN?

    LaRN
    @LaRN
    Senior Developer
    Можно попробовать конструкцию EXISTS.
    Как-то так:
    SELECT
        tt.`email`,
        COUNT(tt.`email`) AS `count`
      FROM
        `e_stat` AS tt
      WHERE NOT EXISTS (
          SELECT 1
            FROM `e_stat`
            JOIN `pb`
              ON `pb`.`e_stat_id`  = `e_stat`.`id`
           WHERE `e_stat`.`msg`   = '68'
             AND `e_stat`.`email` =  tt.`email`) 
           GROUP BY tt.`email`
    Ответ написан
    Комментировать
  • Как уменьшить нагрузку на Mysql запрос на очень нагруженной базе?

    LaRN
    @LaRN
    Senior Developer
    Можно попробовать сделать небольшую нормализации, например перенести из таблицы task три поля ( type, provider, cat ) в отдельную таблицу tasktype, а в исходной таблице оставить только одно поле tasktypeID и это поле поместить в индекс таблицы task вместо предыдущих трех.
    Т.к. у вас запросе условия указаты статичными, то можно вначале наиграть tasktypeID по таблице tasktype, которая не должна быть очень большой и затем идти в индекс от task по двум полям вместо четырёх. Кроме этого индекс в task станет меньше места занимать и это должно ускорить поиск по индексу и его перестраивание при добавлении новых строк.
    Ответ написан
  • Почему не всегда срабатывает код?

    LaRN
    @LaRN
    Senior Developer
    Вот тут немного странно сделано:
    DB::beginTransaction();
    $waitingPayment = HistoryPayment::find($waitingPayment->id);
    if ($waitingPayment->status_transaction === 'success') {
    return false;
    }

    Открываем транзакцию, чекаем что status_transaction === 'success' и выходим не закрывая её и не откатывая. Может вынести проверку до открытия транзакции.
    Просто открытая тут транзакция может, где-то далее не явно использоваться и возможно влиять на то, что что-то потом откатывается при rollback, что не должно откатывать я.

    Есть ещё вызов
    ChangeBalance::dispatch($user->id, $user->balance);
    Он за пределами основной транзакции и не в try, может он влиять на баланс, например если внутри у него ошибка случается?
    Ответ написан
  • Как хранить в базе исторические данные и удалять дубликаты?

    LaRN
    @LaRN
    Senior Developer
    Можно для каждого датчика в оперативной таблице хранить две даты: дата начала интервала постоянства и дата окончания этого интервала. Это такой интервал в котором значение датчика не меняется.
    Т. е. грузим текущие данные и если по датчику значение не поменялось, то просто изменяем дату окончания интервала на дату текущей загрузки, если значение датчика поменялось(отличается от сохраненного в оперативной таблице) , то текущий интервал выгружаем в архивную таблицу, а в оперативной добавляем новую(изменяем существующую) запись для датчика у которой дата начала и дата окончания будет равна дате текущей загрузки, а значение текущему загружаемому значению датчика.
    Т. е. в оперативной таблице всегда количество записей равно количеству датчиков, а в исторической весь скоп предыдущих значений.
    Это должно защитить от того, что с течением времени скорость работы с оперативной таблицей будет деградировать, от того что там будет расти число записей.
    Если же нужно какой-то отчёт строить или выгрузку за период или за прошлые даты, то тут уже нужно будет работать с исторической таблицей и это будет уже не очень быстро, но такие операции обычно не требуется часто выполнять.

    Так как данные грузятся раз в 3-4 дня, наверное не очень критично, что загрузка будет выполнять не мгновенно. Тут наверное проще в несколько этапов сделать: на первом проходе построить список идентификатор датчиков по которым значение не поменялось, затем по этому списку проапдейтить дату окончания интервала на дату текущей загрузки, затем по датчикам которые не попали в список перелить строки в архивную таблицу и наконец поменять для изменённый датчиков в оперативной таблице значение счётчика и даты начала и окончания интервала.
    Всё шаги можно делать массово.
    Ответ написан
    Комментировать
  • Как выводить записи из базы учитывая 2 переменные, количество оценок и саму оценку?

    LaRN
    @LaRN
    Senior Developer
    А прост среднее через sum(rating.meta_value*rating_count.meta_value)/sum(rating_count.meta_value) не поможет?
    Группировку делать как и сейчас по posts.ID.
    Ответ написан
  • Как написать SQL-запрос для данной ситуации?

    LaRN
    @LaRN
    Senior Developer
    Для MSSQL можно так попробовать:
    select ID, max([Date]), sum(case [Type] when 1 then [sum] else -1*[sum] end) 
        from table_name
      group by ID
    Ответ написан
    Комментировать
  • Почему не работает запрос?

    LaRN
    @LaRN
    Senior Developer
    Используйте для передачи параметров в запрос технику описанную вот тут:
    https://www.w3schools.com/php/php_mysql_prepared_s...
    Ответ написан
    Комментировать
  • Почему при добавлении в БД после отправки формы выдаёт такую ошибку?

    LaRN
    @LaRN
    Senior Developer
    В таблице user есть поле auth_key. Для этого поля не задано значения в вашем коде INSERT INTO и не задано значения по умолчанию при создании таблицы. Отсюда и ошибка.
    Ответ написан
    Комментировать
  • Почему mysql не записывает данные если есть хоть одно одинаковое данное?

    LaRN
    @LaRN
    Senior Developer
    Возможно у вас есть у таблицы users уникальный индекс например по полю email. Если так, то дубли при вставке либо вызывают ошибку, либо игнорируют я.
    Ответ написан
  • Как получить количество из нескольких таблиц?

    LaRN
    @LaRN
    Senior Developer
    В вашем варианте нужно осторожнее с union быть, он выкидывает дубли, т.е. если все три запроса вернут например число 5, то результат вычисления вместо 15 будет 5. Чтобы оставить дубли, нужно использовать union all.
    Если прямо в лоб решать вашу задачу, то можно так попробовать:
    SELECT [type], count(1) AS cnt FROM (
    SELECT [type] FROM tab1 AS t1 WHERE t1.date between '2020-01-01' AND '2020-08-15'
    UNION ALL
    SELECT [type] FROM tab2 AS t2 WHERE t2.date between '2020-01-01' AND '2020-08-15'
    UNION ALL
    SELECT [type] FROM tab3 AS t3 WHERE t3.date between '2020-01-01' AND '2020-08-15'
    ) AS t
    group by [type]

    Но если в таблицах много записей, то это может долго работать.
    Ответ написан
  • Как сделать кастомную сортировку с изменений порядка записей?

    LaRN
    @LaRN
    Senior Developer
    Можно дать пользователю возможность в интерфейсе выбрать поля для сортировки и направление сортировки (ASC/DESC) и хранить в итоге для пользователя только сформированную секцию ORDER BY.
    Ответ написан
  • Почему тормозит база?

    LaRN
    @LaRN
    Senior Developer
    Возможно по типу = 14 выдается очень много строк, посмотрите на такую статистику:

    SELECT bls.idstatus, COUNT(1)
    FROM
        SS_B2POS.blank_last_status AS bls
            LEFT JOIN
        SS_B2POS.blanks AS b ON b.idblank = bls.idblank
            LEFT JOIN
        SS_B2POS.clients AS c ON b.idclient = c.idclient
    GROUP BY bls.idstatus;
    Ответ написан
  • Как удалить все сообщения на форуме, кроме первых?

    LaRN
    @LaRN
    Senior Developer
    Можно так попробовать:

    DELETE posts
      FROM posts pp
     WHERE EXISTS(SELECT 1
                    FROM posts pm
                   WHERE pm.authorid = pp.authorid
                     AND pm.id       < pp.id)


    По каждому автору authorid удаляем все сообщения для которых можем найти предыдущее сообщение pm.id < pp.id, таким образом по каждому автору останется только первое сообщение.
    Порядок следования сообщений равен порядку увеличения posts.id, если это не так, то вставьте свой критерий.
    Ответ написан
    Комментировать
  • Как вывести названия столбцов из таблицы?

    LaRN
    @LaRN
    Senior Developer
    Т.е. требуется вывести список полей таблицы?
    Если так, то посмотрите вот эту ссылку.
    https://oooportal.ru/?cat=article&id=1261
    Ответ написан
  • Что за ошибка с GROUP BY в запросе?

    LaRN
    @LaRN
    Senior Developer
    Можно добавить агрегирующий функции и поправить немного группировку:
    SELECT albums.id, albums.name, min(photos.thumb_url)
        FROM `custom_app_bigd_gallery_albums` albums
        LEFT JOIN `custom_app_bigd_gallery` photos ON albums.id=photos.album_id
        WHERE photos.thumb_url IS NOT NULL
        GROUP BY photos.album_id, albums.name
        ORDER BY albums.id DESC
        LIMIT 0, 25
    Ответ написан
    Комментировать
  • В чем ошибка авторизации?

    LaRN
    @LaRN
    Senior Developer
    Похоже вот тут ошибка:

    $user = $db->query("SELECT (id, pName, pPassword) FROM users WHERE pName = '$nick'");
    нужно так:
    $user = $db->query("SELECT (id, pName, pPassword) FROM users WHERE pName = '" . $nick . "'");

    А так переменная $nick в запрос как имя переменной подставляется, а не как значение.
    Ответ написан
  • Как выбрать записи из таблицы, одновременно имеющие несколько значений?

    LaRN
    @LaRN
    Senior Developer
    Можно так попробовать:
    select en.Name
      from empl_services es
     inner join services ss
             on ss.id     = es.services_id
            and ss.title in ('Крутит гайки', 'Гнёт арматуру')
     inner join employee em
             on ss.id     = es.employee_id
     group by en.Name
    having count(1) = 2
    Ответ написан
    Комментировать
  • Как оптимально спроектировать таблицы в бд?

    LaRN
    @LaRN
    Senior Developer
    Я бы за основу взял устройство ЕСКД-шной спецификации (там есть все необходимое).

    Например так:
    Таблица содержащую описание детали(это там, где короб/вал и прочие детали.)
    tEntity (id, Name)

    Таблица содержащая параметры данной детали(это там где размеры детали и прочее)
    tEntityParam(id, EntityID, ParamType, ParamValue)
    Тут ParamType это тип параметра (длина/ширина/высота/марка стали...) - возможно для типов потребуется завести отдельную таблицу с описанием.
    А ParamValue значение этого параметра.

    Таблица описание типа (он же сборка - набор из нескольких деталей):
    tAssemblyType(id, Name, EntityID, Quantity)
    В этой таблице описываем из каких деталей (тип и количество - по сути спецификация) состоит сборка.

    Таблица описание изделия (Возможно что изделие включает в себя несколько сборок):
    tOrder(id, AssemblyTypeID, Name, Quantity)
    Ответ написан
    Комментировать
  • Как написать SQL запрос?

    LaRN
    @LaRN
    Senior Developer
    Можно так попробовать.
    Я тут учитывал кейсы, когда время выхода больше времени входа.

    SELECT userGUID, areaGUID, timeHappened AS times
      FROM users in_u
      LEFT JOIN users out_u
             ON out_u.userGUID     = in_u.userGUID
            AND out_u.areaGUID     = in_u.areaGUID
            AND out_u.inOut        = 2
            AND out_u.timeHappened > in_u.timeHappened
     WHERE in_u.inOut  = 1
       AND out_u.inOut IS NULL
    ORDER BY userGUID, areaGUID
    Ответ написан
    Комментировать
  • Чем заменить конструкцию WHERE id>count(id)?

    LaRN
    @LaRN
    Senior Developer
    Можно расчет count(id) вынести в подзапрос, тогда первый вариант должен сработать.
    https://dev.mysql.com/doc/refman/8.0/en/subqueries.html

    Если в коде, то как-то так:
    SELECT * 
      FROM table 
    WHERE id>(SELECT max(id) 
                         FROM table 
                       WHERE date < CURDATE()) 
       LIMIT 10
    Ответ написан