Ответы пользователя по тегу MariaDB
  • Как динамически делать выборку по дням, неделям или месяцам?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Как вы видите, тут идёт выборка за 2 дня: 2024-04-09 и 2024-04-10. Но проблема в том, что количество дней указывает пользователь и их может быть сколько угодно. Подскажите, как правильно сделать, что если пользователь указал, например, 10 дней, то выборку сделать за 10 дней (начиная от сегодня)?

    Я вижу, что количество выходных полей зависит от внешних условий. То есть структура выходного набора динамическая, а всё вместе это по сути сводная таблица. То есть штука совсем даже не реляционная.
    Да, некоторые СУБД имеют встроенные средства для формирования PIVOT TABLE. Yо вот у MariaDB с этим не очень.

    Рекомендую - на стороне СУБД получать нормализованный набор записей (country_id, ts, MAX(hangup_rate), MAX(all_answered)), а сводную строить уже на клиенте.
    Ответ написан
    Комментировать
  • Почему не получаются значения NEW в триггере BEFORE UPDATE?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Для всех полей, которые не указаны явно в запросе на добавление (то есть поля явно перечислены в предложении INSERT, но это не все поля таблицы, есть неупомянутые в списке поля), в шаблон вставляемой записи помещается указанное в структуре таблицы значение по умолчанию. Если таковое отсутствует, то в шаблон помещается NULL.

    Поле-автоинкремент не имеет значения по умолчанию. Генерация нового автоинкрементного значения производится после выполнения всех BEFORE триггеров. Отсюда и NULL в указанной ситуации.

    PS. https://xyproblem.info/
    Ответ написан
  • Можно ли составить mysql запрос с выборкой не определенного множества полей?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Можно ли одним запросом вывести все товары и свойства которые соответствуют данному товару
    id товара, название, свойство, значение......все свойства, значения.

    1; Ручка; Цвет; Синий; Цена; 10
    2; Нож; Материал; Цена; 200; Рукоятка; Дерево; Фото; Есть;

    Приведённый хреново форматированный текст не позволяет понять, где какое поле, и какой в нём тип данных.

    Полное ощущение, что автору требуется куча колонок (в смысле полей в структуре выходного набора). ТО есть если свойство одно, полей 4, если свойств 2, полей 6, и так далее...

    Если так, то требуемый результат называется "сводная таблица" (pivot table). Это совсем даже не реляционная структура, у которой нет и тени шанса попасть в стандарт, а потому практически ни одной СУБД штатно не поддерживается. Из популярных оно есть исключительно в SQL Server, да и там скорее исторически сложилось, чем нужно было.

    В MySQL / MariaDB ничего подходящего нет. И если кому оно реально необходимо, приходится возиться руками - хранимая процедура, динамический код... хотя на порядок разумнее оставить данные в EAV, а сводную таблицу строить на клиенте на его сервисе отчётов.

    Если же устроит выдача всех свойств, собранных в одно сериализованное поле (например, объект JSON) - то это обычная группировка и агрегация.
    Ответ написан
    Комментировать
  • Как сделать проверку базы данных, на наличие новых записей?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Если количество новых записей невелико (в пределах тысячи), то возможное решение - триггер на основной таблице, который копирует свежевставленные записи в дополнительную таблицу. Тупо один к одному. А процедура проверки на свежие записи столь же тупо выгребает из этой дополнительной таблицы всё туда упавшее, после чего чистит её.
    Ответ написан
  • Что лучше, по одной или несколько записей при INSERT?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Запись пакетом быстрее и менее нагрузочна, но выше вероятность потери при сбоях.

    PS. 40 записей в секунду - это в общем-то ни о чём..
    Ответ написан
    Комментировать
  • Как узнать, имеет ли столбец unique?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Сведения об UNIQUE constraint (включая и PRIMARY KEY) могут быть получены запросами
    SELECT *
    FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
    WHERE TABLE_SCHEMA = DATABASE() /* либо 'database_name' */
      AND TABLE_NAME = 'table_name'
    
    SELECT *
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_SCHEMA = DATABASE()
      AND TABLE_NAME = 'table_name'


    The INFORMATION_SCHEMA KEY_COLUMN_USAGE Table
    The INFORMATION_SCHEMA COLUMNS Table
    Ответ написан
  • Удаление БД как папок из mariadb?

    @Akina
    Сетевой и системный админ, SQL-программист.
    1. На проблемном сервере:
      • Создать папки баз.
      • Запустить сервер в режиме восстановления (InnoDB Recovery Modes).
      • Дропнуть базы.

    2. Если не удаётся запуститься даже в режиме восстановления:
      • Восстановить БД из бэкапа на другом инстансе сервера
      • Скопировать каталоги баз на проблемный сервер
      • См. п. 1.

    Ответ написан
    Комментировать
  • Как посчитать общую длительность времени между строками определенной выборки в MySQL?

    @Akina
    Сетевой и системный админ, SQL-программист.
    WITH cte AS ( SELECT *, 
                         LAG(`datetime`) OVER (PARTITION BY login ORDER BY `datetime`) lag_datetime, 
                         LAG(event) OVER (PARTITION BY login ORDER BY `datetime`) lag_event 
                  FROM history )
    SELECT login, SUM(TIMESTAMPDIFF(MINUTE, lag_datetime, `datetime`)) duration
    FROM cte
    WHERE (event, lag_event) = (2,1)
    GROUP BY login;

    https://dbfiddle.uk/?rdbms=mariadb_10.6&fiddle=398... (исходные данные подправлены).
    Ответ написан
    1 комментарий
  • Как выбрать только те записи, которые не пересекаются и только те, которые пересеклись?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Используем [NOT] EXISTS
    SELECT *
    FROM user_friend uf1
    WHERE [NOT] EXISTS ( SELECT NULL
                         FROM user_friend uf2
                         WHERE uf2.friend_user_id = uf1.user_id )

    При WHERE EXISTS выбираются пары друзей (записи, имеющие обратную пару), при WHERE NOT EXISTS - записи, не имеющие обратной пары.

    Если для записей, имеющих обратную, нужна только одна пара из двух - добавляем во WHERE внешнего запроса ещё одно условие AND friend_user_id > user_id.
    Ответ написан
    Комментировать
  • LEFT JOIN по условию IF?

    @Akina
    Сетевой и системный админ, SQL-программист.
    DROP PROCEDURE IF EXISTS get_artist;
    DELIMITER ;;
    CREATE PROCEDURE get_artist(IN artist_id integer(11), IN show_links integer(1))
    BEGIN
        CASE WHEN show_links=1
             THEN 
                 SELECT * 
                 FROM artist 
                 where id = artist_id;
             ELSE  
                 SELECT * 
                 FROM artist 
                 LEFT JOIN artist_social_links ON artist_social_links.artist_id = artist_id 
                 where id = artist_id ;
        END CASE;
    END;;
    DELIMITER ;
    CALL get_artist(196796, 1);
    Ответ написан
    3 комментария