Задать вопрос
  • SQL запрос как создать 9999 записей с итерацией чисел?

    @Akina
    Сетевой и системный админ, SQL-программист.
    1. Вот оно надо, каждый раз заботиться об установлении значений полей DATE_CREATE/DATE_UPDATE?

    ALTER TABLE tablename
    MODIFY COLUMN date_create TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    MODIFY COLUMN date_update TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

    Всё, теперь они сами будут заботиться о правильном значении. Точнее, сервер будет об этом заботиться. Если, конечно, коду не придёт в голову устанавливать значения этих полей явно (нафига бы только - лишняя же работа).

    2. Для выполнения операции используем рекурсивный CTE (помним, что поля DATE_CREATE/DATE_UPDATE сами заботятся о правильном значении, как и автоинкрементный первичный ключ):

    INSERT INTO tablename (active, user_id, value)
    WITH RECURSIVE
    cte AS ( SELECT 1 num
             UNION ALL
             SELECT num + 1 FROM cte WHERE num < 9999 )
    SELECT 1, 1, num
    FROM cte;


    Возможно, предварительно надо установить достаточное значение для сессионной переменной:SET SESSION cte_max_recursion_depth = 10000;

    Если версия MySQL старая и не понимает CTE, то

    INSERT INTO tablename (active, user_id, value)
    SELECT 1, 1, 1 + t1.num + t2.num * 10 + t3.num * 100 + t4.num * 1000 AS value
    FROM       (SELECT 0 num UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1
    CROSS JOIN (SELECT 0 num UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2
    CROSS JOIN (SELECT 0 num UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3
    CROSS JOIN (SELECT 0 num UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t4;
    HAVING value <= 9999;
    Ответ написан
    1 комментарий
  • Как правильно спроектировать связь БД между двумя товарами?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Вопрос: как мне правильно спроектировать таблицу для связей между этими товарами. Чтобы каждый из этих товаров ссылался друг на друга?

    CREATE TABLE groups_of_goods (
        group_id BIGINT UNSIGNED NOT NULL,
        product_id BIGINT UNSIGNED NOT NULL,
        PRIMARY KEY (group_id, product_id),
        FOREIGN KEY fk_product (product_id) REFERENCES product (product_id)
    );


    Соответственно если твои труселя входят в одну группу и ссылаются друг на друга, то в таблице будут 2 записи - (123, 10) и (123, 15).

    Кстати, такая схема обеспечивает и принцип "вассал моего вассала ...". Т.е. "пиджак малиновый" может ссылаться на "брюки малиновые" (через группу 456) и "пиджак в полоску" (через группу 789), но при этом последние два друг на друга ссылаться не будут, ибо разные группы.
    Ответ написан
    2 комментария
  • Какой должен быть тип строки в БД для номера телефона, состоящего из одних цифр?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Насколько я понимаю, надо не только чистить для сохранения и последующего удобного использования, но и возвращать их на место при передаче данных обратно на сайт для отображения или корректировки, верно?

    Если так, то предлагаю с самим полем ничего не делать, пусть себе будет текстовое и со всякой фигнёй. А для использования создать ещё одно, вычисляемое, поле, в которое класть очищенное и приведённое к числовому значение.

    Т.е. если сейчас имеется
    CREATE TABLE users (
        ...
        phone VARCHAR(255),
        ....
    );

    то выполняем
    ALTER TABLE users ALGORITHM = INPLACE
        ADD COLUMN phone_num BIGINT UNSIGNED AS (REGEXP_REPLACE(phone, '[^0-9], ''')) VIRTUAL,
        INDEX idx_phone_num (phone_num);


    Что это даёт?

    Выражение вычисляемого поля чистит строковое значение от всего, что не цифра, после чего значение преобразуется в тип данных поля, т.е. BIGINT UNSIGNED. Отлично, число получено.

    Поле объявлено как VIRTUAL. Это означает, что его значение не хранится в таблице, а вычисляется каждый раз, когда оно потребуется. Но мы создаём по этому полю индекс. Соответственно сервер может не вычислять значение, а извлечь его из индекса. Ещё лучше, если это поле будет включено в композитные индексы вместо поля phone - тогда вероятность, что сервер будет извлекать значение из индекса, увеличится.

    Конечно, можно было бы сделать поле STORED и не морочиться с индексом. Но тогда процесс изменения структуры таблицы будет достаточно длительным, потому что такая операция не может быть INPLACE и требует COPY. Впрочем, это может оказаться более подходящим в определённых условиях.

    Да, следует помнить, что в это поле нельзя записывать значения ни при INSERT, ни при UPDATE - такая операция приведёт к ошибке. Так что про запросы без указания списка полей придётся забыть... ну и SELECT * - тоже забыть.
    Ответ написан
    Комментировать
  • Как правильно сделать Mysql "точный" like запрос?

    @Akina
    Сетевой и системный админ, SQL-программист.
    1. Использовать не LIKE, а функции поиска подстроки (INSTR или LOCATE)
    2. Задать требуемый collation (вплоть до BINARY)
    Ответ написан
    Комментировать
  • Как получить все проекты, у которых нет связи с определенным юзером через 2 таблицу?

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

    SELECT p.*
    FROM project p
    WHERE NOT EXISTS ( SELECT NULL
                       FROM project_user u
                       WHERE p.project_id = u.project_id
                         AND u.user_id = 4 )
    Ответ написан
    Комментировать
  • Можно ли доверять коду ошибки Mysql?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Server Error Message Reference

    Error number: 1452; Symbol: ER_NO_REFERENCED_ROW_2; SQLSTATE: 23000

    Message: Cannot add or update a child row: a foreign key constraint fails (%s)

    InnoDB reports this error when you try to add a row but there is no parent row, and a foreign key constraint fails. Add the parent row first.

    Данная ошибка всегда порождается событием неудачной проверки ограничения ссылочной целостности. Так что можете смело доверять причине.

    Или перед вставкой нужно создать запрос на проверку существования такой записи в связующей таблице?

    А вот задайте себе вопрос - откуда возьмётся то самое значение user_id = 3, которое Вы собираетесь вставить? я не вижу иного способа получить данное значение кроме как сделать запрос в родительскую таблицу. А коли из неё вернётся нужное значение - то запись, из которой взято это значение, совершенно очевидно в таблице есть.
    Ответ написан
    5 комментариев
  • Как лучше реализовать динамические поля?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Принципиально есть два варианта.

    Первый, уже указанный в комментарии от Ерлан Ибраев, EAV.

    Второй - сериализация динамических параметров. JSON, XML и т.п.

    В обоих вариантах по мере доработки параметры могут легко переноситься из динамического хранилища в постоянное. Также оба варианта допускают и множественные значения - в том числе в постоянном и временном хранилищах одновременно (что к тому же даёт потенцию одноступенчатой приоритезации).

    Явный недостаток обоих способов - использование унифицированного типа данных в таблице (как минимум строковый, а данные запросто могут потребовать ещё и binary collation) вне зависимости от реального типа сохраняемых данных. Ещё один явный недостаток - необходимость выноса контроля целостности на клиентский уровень.

    Что выбрать? а вот это уже зависит от того, что именно делается с данными.

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

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT CASE valuta WHEN 1 THEN price
                       WHEN 0 THEN price * 73
                       ELSE NULL 
                       END AS price_in_rub, 
           ...
    FROM ...
    WHERE ...
    Ответ написан
    1 комментарий
  • Как правильно делать JOIN таблиц?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Есть ли разница джоинов этих двух строк, с точки зрения нагрузки на БД?

    Оба запроса - INNER JOIN. Если не используется STRAIGHT_JOIN, то сервер гарантированно построит для обоих запросов один и тот же план выполнения.

    Более того, если Вы почитаете внимательно, как именно сервер выполняет и оптимизирует запросы, то узнаете, что сервер фактически оба этих запроса приводит к картезианскому произведению с отбором. Вернее, препроцессинг выглядит так, словно сервер выполняет такое приведение.
    Ответ написан
    Комментировать
  • Как удалить содержимое БД Mysql?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Самое простое - сделать бэкап только структуры, без данных (mysqldump --no-data, https://dev.mysql.com/doc/refman/8.0/en/mysqldump....), удалить БД, восстановить. Само собой, не забыть забэкапить процедуры/триггеры/прочее.
    Ответ написан
    Комментировать
  • Зачем нужны alias-ы в БД?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Основное назначение алиасов - устранение неоднозначности при наличии одноимённых таблиц/полей.

    Дополнительно - удобство именования, особенно когда оригинальные имена длинные.

    Если ещё смыслы, но они минорны.
    Ответ написан
    Комментировать
  • Как отсортировать разные группы по разным методам?

    @Akina
    Сетевой и системный админ, SQL-программист.
    ORDER BY CASE WHEN parent_id IN (0,51,52)
                  THEN 1
                  ELSE 2 
                  END ASC,
             CASE WHEN parent_id IN (0,51,52)
                  THEN name
                  ELSE ''
                  END ASC,
             CASE WHEN parent_id IN (0,51,52)
                  THEN ''
                  ELSE name
                  END DESC
    Ответ написан
    Комментировать
  • Как правильно указать значение SET?

    @Akina
    Сетевой и системный админ, SQL-программист.
    пробовал делать это через "?" и "*" , но не получается

    Для того. чтобы вставляемое значение не квотировалось, следует использовать плейсхолдер из 2 знаков вопроса:
    PreparedStatement ps = plugin.SQL.getConnection().prepareStatement("UPDATE PlayerBlocks SET ?? = ? WHERE UUID=?");

    Тогда первый передаваемый параметр - имя поля для обновления. 2 и 3 соответственно значения (новое и для условия отбора).
    Ответ написан
    4 комментария
  • Можно ли преобразовать отступы в ячейках в табуляцию?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Сами отступы в табуляции превратить не получится.

    Создайте функцию:
    public function get_indent(rng as range) as integer
        get_indent = rng.indentlevel
    end function


    В отдельной колонке используйте её:
    B1 = get_indent(A1)

    Соответственно при экспорте Вы получите дополнительную колонку с уровнем. После импорта - используйте это значение.

    Альтернативно можете ещё в одной колонке на основании значений навтыкать в начало нужное количество табуляций, и экспортировать только эту колонку.
    Ответ написан
    3 комментария
  • Если в роутере есть usb порт, после прошивки он будет поддерживать модем?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Если в роутере есть usb порт, после прошивки он будет поддерживать модем?

    Зависит от прошивки.

    мне сказали что, некоторые прошивки меняют TTL модема, даже если он фиксированный. Как это может быть, если TTL модема фиксированный?
    Изменение TTL пакета при маршрутизации задаётся программно (начальное значение - это константа, записанная в прошивке). Неудивительно, что в новой прошивке она может быть не такая, как в старой. В общем, тоже зависит от прошивки.
    Ответ написан
    3 комментария
  • Какой IP адрес будет у маршрутизатора mikrotik, если к нему подключить 4g модем?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Ответ зависит от того, как именно настроен модем.

    Модем может быть настроен в режим роутера. Тогда он получает внешний адрес (WAN) от оператора/провайдера, внутренний (LAN) зашит в его настройках (и это другая, серая, подсеть). В этом случае Микротик должен быть настроен на присвоение себе статического адреса из LAN подсети модема, либо, если на модеме на LAN включен DHCP, может получать адрес динамически (что делать в общем настоятельно не рекомендуется).

    Модем может быть настроен в режим моста. В этом случае он не имеет никаких адресов (вернее, имеет только внутренний адрес интерфейса управления, обычно доступный только через LAN-интерфейс) и просто выполняет роль конвертера интерфейса из WiFi в медь. Тогда Микротик по этому установленному каналу должен получать динамический адрес интерфейса от оператора/провайдера либо быть настроен на статический адрес, выданный оператором/провайдером. Впрочем, такой сценарий маловероятен.

    В какую сторону гуглить?


    Для начала - прочитать и изучить мануал на модем, и изучить его настройки. Ну и посмотреть, что насчёт настроек говорит оператор.
    Ответ написан
    Комментировать
  • Как узнать, что ячейка является объединенной?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Для определения, является ли ячейка объединённой, есть куча способов.

    Например, cell.CurrentRegion.Count возвращает количество отдельных ячеек объекта cell - соответственно для объединённой ячейки он вернёт значение больше единицы.

    Если ячейка является объединённой, то противоположный угол можно получить так: cell.Offset(1,1).Offset(-1,-1).Address. Зная ядрес ячейки и адрес противоположного угла, несложно обычной конкатенацией построить адрес для обратного объединения.
    Ответ написан
    Комментировать
  • Почему Select выдает меньше колонок чем в нем прописано?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Причина простая. Лапша вместо кода. Это и не позволяет понять, что есть что.

    Отформатируем:

    with AAA(A) as (
        select 1 union 
        select 2 union 
        select 3 union 
        select 4 union 
        select 5
    )
    select 'А01' as "id",
           1 as "sensor",
           generate_series('2021-07-01 00:00:00', '2021-07-31 23:59:59', '10 sec'::interval) as "time",
           t.status[floor(random()* 4 + 1)::int] 
    from (select array_agg(distinct AAA.A) as "status" from AAA ) as t ,
         round((random()* 400 - 200)::numeric, 2) as "value"

    Теперь сразу видно, что value не является полем выходного набора. Это алиас синтетической таблицы в секции FROM.

    PS. За логику и даже просто за синтаксическую корректность я так и вовсе молчу...
    Ответ написан
    1 комментарий
  • Как создать текстовые файлы из списка в .txt?

    @Akina
    Сетевой и системный админ, SQL-программист.
    for /f %x in (file.txt) do echo.>%x.txt
    Кодировка текстового файла должна соответствовать кодировке имён в файловой системе.
    Ответ написан
  • Какой необходимо составить запрос mysql для генератора случайного поста по рейтингу?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Ну типа так.
    WITH cte AS (
        SELECT *, SUM(rating) OVER (ORDER BY id) cum_rating
        FROM table
    )
    SELECT
    FROM cte t1
    JOIN (SELECT RAND() * MAX(cum_rating) rnd_rating
          FROM cte) t2 ON t2.rnd_rating BETWEEN t1.cum_rating - t1.rating AND t1.cum_rating

    Реально, конечно, не BETWEEN, а два неравенства, по верхней границе - строгое.
    Ответ написан