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

    @Akina
    Сетевой и системный админ, SQL-программист.
    Обычно если в запрос может быть передано значение, а может и нет, делают так:
    ... AND (column = {parameter} OR {parameter} IS NULL) ..

    При подстановке параметра сервер уже на этапе построения плана выполнения запроса, зная значение {parameter}, получит либо
    ... AND (column = {parameter} OR FALSE) .. ==> ... AND (column = {parameter}) ..
    либо
    ... AND (column = {parameter} OR TRUE) .. ==> ... AND (TRUE) ...

    PS. Чтобы не геморроиться с определением, когда ставить WHERE, начальный шаблон делают такой:
    SQL = "SELECT * FROM USERS WHERE 1=1 {} LIMIT %s OFFSET %s"

    и все дополнительные условия формируют в виде
    AND {условие}
    Тогда не надо оглядываться, первое это условие или нет.

    Само же условие 1=1 будет обращено в TRUE и отброшено опять-таки на этапе построения плана.
    Ответ написан
    2 комментария
  • Как составить sql запрос?

    @Akina
    Сетевой и системный админ, SQL-программист.
    WITH
    cte AS (
      SELECT *, ROW_NUMBER() OVER (PARTITION BY document_id ORDER BY job_id DESC) rn
      FROM my_table
      )
    SELECT document_id, job_id, person_id
    FROM cte 
    WHERE rn = 1;

    И в качестве бонуса
    SELECT DISTINCT 
           document_id,
           MAX(job_id) OVER (PARTITION BY document_id) job_id,
           FIRST_VALUE(person_id) OVER (PARTITION BY document_id ORDER BY job_id DESC) person_id
    FROM my_table
    Ответ написан
    Комментировать
  • SQLite Как выбрать записи, текстовое поле которых содержит подстроку, регистронезависимо?

    @Akina
    Сетевой и системный админ, SQL-программист.
    LIKE регистронезависим.
    GLOB регистрозависим.
    REGEXP - как напишешь регулярку, так и будет.
    Ответ написан
    Комментировать
  • Как составить запрос на выборку авторов в SQL?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT *
    FROM Author
    WHERE NOT EXISTS (
        SELECT NULL
        FROM Book
        WHERE Author.Authorld = Book.Authorld
          AND Book.PublishDateTime >= CURRENT_DATE - INTERVAL 2 YEAR
        )
    Ответ написан
  • Как правильно построить запрос в БД?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT table1.*, 
           EXISTS ( SELECT NULL
                    FROM table2
                    WHERE table2.table1_id = table1.id
                       AND table2.date = @needed_date
                    ) AS row_exists
    FROM table1

    Если точная дата внутри месяца неизвестна, то
    WHERE table2.date BETWEEN @needed_month_1st_day AND @needed_month_last_day
    Ответ написан
    Комментировать
  • Как составить запрос sql?

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

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

    Вариант соответственно второй - считать все укрупнёнки в момент записи текущих данных. Удалять/чистить лучше отдельной эвент-процедурой, если старая укрупнёнка недельку полежит, никто не помрёт. Вопрос отдельных таблиц под разные укрупнёнки - только если их структура различна в зависимости от периода, иначе одна таблица и поле маркер - диапазон периода записи.
    Ответ написан
  • Как создать корректный SQL триггер?

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

    ??? Какое ещё "поле"? может, запись? ну так для этого существует INSERT ... ON DUPLICATE KEY UPDATE Statement.
    А триггеры - они для дела, а не для баловства..
    Ответ написан
    Комментировать
  • Как соединить строки в одну?

    @Akina
    Сетевой и системный админ, SQL-программист.
    MS Access не имеет функции групповой конкатенации.

    Проблема решается путём создания пользовательской функции и использования её в запросе.

    Function group_concat(category As String) As String
    With CurrentDb.OpenRecordset("SELECT [Цех] FROM [Имя таблицы] WHERE [Продукция] = '" & category & "'")
        group_concat = ""
        .MoveFirst
        While Not .EOF
            group_concat = group_concat & "," & ![Цех]
            .MoveNext
        Wend
        .Close
    End With
    group_concat = Mid(group_concat, 2)
    End Function

    Поскольку пользовательская функция - скалярная, и не агрегатная, её нужно оборачивать какой-либо агрегатной функцией.
    SELECT [Продукция], MAX(group_concat([Цех])) AS [Цех]
    FROM [Имя таблицы]
    GROUP BY [Продукция];


    PS. Конечно, функцию можно сделать более универсальной, передавая в неё имена таблицы и полей, а также маркер типа данных поля категории.

    ---
    Ну или взять готовую DConcat() от Patrick G. Matthews: https://www.experts-exchange.com/articles/2380/Dom...
    Ответ написан
    Комментировать
  • Как вывести из sql таблицы все строки с совпадающими значениями?

    @Akina
    Сетевой и системный админ, SQL-программист.
    WITH cte AS (
        SELECT a, b, c, COUNT(*) OVER (PARTITION BY a, c) cnt
        FROM table
    )
    SELECT a, b, c
    FROM cte 
    WHERE cnt > 1
    Ответ написан
    1 комментарий
  • Не хочет связываться таблица почему?

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

    Надо, чтобы в поле cat_id таблицы post уже присутствовало значение, которое ты присваиваешь полю id во вставляемой записи.
    Ответ написан
    1 комментарий
  • Как получить timestamp,обрезав пустое время?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Не делай так. Единообразие - это очень полезная штука. Если оставить нулевую компоненту времени, то конечному пользователю не придётся думать, действительно ли там нули, или время не отображается из-за какого-то косяка..
    Ответ написан
  • Как можно использовать Foreign Key?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Запомните одну вещь. Многие её забывают или не знают, и из этого проистекают все их проблемы.

    Внешний ключ (FOREIGN KEY) - это ПРАВИЛО. Всё остальное - либо дополнения, либо следствия. Народ начинает рассказывать про индексы и прочее - НЕТ! Не включайте всё это в определение собственно внешнего ключа.

    Хотя оно хранится в структуре таблицы, оно является не частью структуры таблицы, а инструкцией, которая будет обрабатываться подсистемой контроля целостности и непротиворечивости данных - есть такая в составе SQL-сервера.

    Это правило устанавливает, что при добавлении/изменении значения следует проверить существование нового значения в ссылочной таблице. И наоборот - при удалении следует проверить отсутствие удаляемого значения в ссылающейся таблице. То есть правило работает в обе стороны - влияет не только на таблицу, в которой оно определено, но и на упомянутую в правиле таблицу, при этом в структуре ссылочной таблицы никакого упоминания о существовании этого правила нет. Но, поскольку подсистема контроля - это подсистема уровня сервера, то ей плевать, где прописано.

    Это правило может быть дополнено опциями каскадной операции ON DELETE/UPDATE - в этом случае после контроля нового значения подсистема даёт дополнительную команду на выполнение указанных в опции изменений зависящих данных.

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

    Также создание внешнего ключа приводит к выполнению дополнительного контроля такого индекса поддержки, если он удаляется. Если нет другого индекса, который может использоваться для поддержки, то операция удаления индекса будет заблокирована.
    Ответ написан
    Комментировать
  • Как сделать SQL запрос из двух таблиц?

    @Akina
    Сетевой и системный админ, SQL-программист.
    В синтаксисе MySQL:
    SELECT c.name category_name, p.id post_id, p.name post_name, p.title post_title
    FROM posts p
    JOIN categories c ON p.category_id = c.id
    UNION ALL
    SELECT name, NULL, NULL, NULL
    FROM categories 
    ORDER BY category_name, post_id IS NOT NULL

    Соответственно если в поле post_id обнаруживается NULL, то в этой записи категория, и она рисуется как категория. Если же там не NULL - то это пост, и он рисуется со смещением.

    Дурь, конечно, но для сельской местности сойдёт..
    Ответ написан
    1 комментарий
  • Как реализовать first_value(field) с фильтром на field внутри окна?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT 
      *,
      FIRST_VALUE(CASE WHEN banner_id IN (13,14,15,17)
                       THEN banner_id 
                       END) OVER (PARTITION BY id
                                  ORDER BY CASE WHEN banner_id IN (13,14,15,17)
                                                THEN banner_id 
                                                END DESC NULLS LAST) max_banner_id_1,
      FIRST_VALUE(CASE WHEN banner_id IN (4,177,178)
                       THEN banner_id 
                       END) OVER (PARTITION BY id
                                  ORDER BY CASE WHEN banner_id IN (4,177,178)
                                                THEN banner_id
                                                END DESC NULLS LAST) max_banner_id_2
    FROM test
    ORDER BY banner_id
    Ответ написан
    1 комментарий
  • Подсчёт кол-ва детей у сотрудников access?

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

    Топнуть правым батоном точно в соединяющую линию, выбрать Параметры объединения. Итогово должна быть стрелка от Список к Дети.

    После этого - группировка по всем полям из Список и количество из Дети.
    Ответ написан
    Комментировать
  • Что такое PRIMARY KEY, CONSTRAINT, FOREIGN KEY, REFERENCES, INSERT INTO и для чего они нужны?

    @Akina
    Сетевой и системный админ, SQL-программист.
    PRIMARY KEY - первичный ключ. Поле, комбинация полей либо выражение (последнее MySQL не поддерживает), которое не может быть NULL и не допускает дубликатов (уникально для каждой отдельной записи в пределах таблицы). Поддерживается путём создания соответствующего уникального индекса и наложением ограничения NOT NULL на все используемые в выражении поля. По факту - однозначно идентифицирует запись. Кроме того, в MySQL выражение первичного ключа является кластерным индексом. См. Индекс -> Уникальный индекс -> Первичный индекс.

    CONSTRAINT - ограничение. Правило, которое не допускает создания записи, для которой значение выражения ограничения имеет значения FALSE (можно TRUE или NULL).

    FOREIGN KEY - внешний ключ. Ограничение, которое требует, чтобы указанное выражение для текущей записи присутствовало среди значений указанного выражения референсной таблицы (допускается и внешний ключ на ту же таблицу). Точнее, чтобы такая проверка присутствия не возвращала FALSE (можно TRUE или NULL).

    REFERENCES - определяет референсную таблицу и референсное выражение.

    INSERT INTO - запрос, вставляющий новые записи в таблицу.
    Ответ написан
    Комментировать
  • Выбрать строку из БД по значениям связанной таблицы?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT rule.id, rule.path, rule.content, rule.cat_id 
    FROM rule
    JOIN rule_options ON rule.id = rule_options.rule_id
    WHERE rule_options.option IN (4670, 5492)
    GROUP BY 1,2,3,4
    HAVING COUNT(DISTINCT rule_options.option) = 2;
    Ответ написан
    2 комментария
  • Как добавить запись в бд при условии, что она не была до этого добавлена?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Во-первых, надо создать в таблице уникальный индекс по полю, которое не должно содержать дубликатов.
    Во-вторых, надо использовать INSERT IGNORE INTO, чтобы дублирование одного значения не обваливало весь вставляемый массив. Либо REPLACE INTO, если при дублировании надо полностью заменить старую запись новой. Либо INSERT ODKU, если надо обновить старые данные новыми по некоей логике (например, вставить значения в поля, в которых раньше было NULL, а теперь пришло что-то определённое). Это - для MySQL, в других СУБД синтаксис с аналогичными возможностями будет иным.
    Ответ написан
  • Как работать с файлом SQL объемом 20 ГБ?

    @Akina
    Сетевой и системный админ, SQL-программист.
    В комментариях выше фиксируются следующие факты:
    • используемая СУБД - MySQL
    • (вероятно) дамп - MySQL либо MariaDB
    • дамп поделен на несколько частей
    • задача - периодическая

    Соответственно некоторые соображения в дополнение к сказанному ранее.

    Если дамп выполнялся штатной утилитой (вряд ли иначе), то он содержит кучу комментариев, которые позволяют без особых проблем поделить дамп на отдельные файлы - дамп только структуры и дамп только данных. Даже в автоматическом режиме (программно), и уж тем более вручную. Поскольку нужны данные только по пользователям, то после описанного выше разделения можно безболезненно вырезать всё ненужное из дампа структуры (лишние таблицы, всякие процедуры-функции-триггеры, индексы и внешние ключи - всё это нафиг не нужно при восстановлении, а если нужно для эффективности выборки, лучше создать индексы после заливки данных), а также просто убрать дампы данных ненужных таблиц. И скорее всего объём информации для восстановления после такой чистки уменьшится на порядок, а то и больше.
    Ответ написан
    Комментировать