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

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

    Передача части запроса, которая потом будет встроена в текст запроса - плохая идея, ибо чревато инъекцией. Условное выражение на основании переданного параметра этого недостатка лишено, но похоронит возможность использования индексов для сортировки, если они могут быть применены в частной форме запроса.
    Ответ написан
    2 комментария
  • Group by. Как отфильтровать запрос?

    @Akina
    Сетевой и системный админ, SQL-программист.
    По показанным данным и тому, что удалось выудить из описания и комментариев, мне кажется, что достаточно для каждой группы вернуть одну запись с максимальным в группе значением quantity. Это делается запросом
    WITH cte AS (
        SELECT *, ROW_NUMBER() OVER (PARTITION BY group_id ORDER BY quantity DESC) rn
        FROM tablename
    )
    SELECT *
    FROM cte
    WHERE rn = 1;


    Запрос предполагает, что для всех записей группы значение minimum одинаково. Если это не так - использовать ORDER BY quantity>minimum DESC, quantity DESC.

    Запрос предполагает, что в группе нет дубликатов по quantity. Если это не так - вернётся случайный из дубликатов с максимальным значением поля. Если нужен определённый из них - расширить соотв. образом ORDER BY.

    Если версия MySQL старая и не поддерживает ни CTE, ни оконные функции - использовать эмуляцию ROW_NUMBER() на базе UDV в подзапросе.
    Ответ написан
    Комментировать
  • Как получить 100 записей, после записи с определённым uuid?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Использовать 2 копии таблицы. Одну для получения даты по заданному UUID, вторую для выборки записей.
    SELECT t1.*
    FROM table t1
    JOIN table t2 ON t2.uuid = @uuid1 
                 AND t1.createdAt > t2.createdAt
    ORDER BY createdAt ASC LIMIT 100
    Ответ написан
    Комментировать
  • Как изменить значение в JSONB?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Надо указывать полный путь.
    select jsonb_value,
           jsonb_set(jsonb_value, '{requisites,kpp}', '"777"', false)
    FROM test;

    https://dbfiddle.uk/?rdbms=postgres_12&fiddle=3cfb...

    PS. Вообще менять строковый атрибут на числовой - штука небезопасная. В приложении это может аукнуться - оно-то не в курсе...
    Ответ написан
    1 комментарий
  • Doctrine как получить расхождение двух запросов?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Делаю так:
    SELECT * FROM tbl1 EXCEPT SELECT * FROM tbl2

    Структуры таблиц совпадают?

    Тогда
    SELECT t1.*
    FROM tbl1
    LEFT JOIN tbl2 ON tbl1.primary_key = tbl2.primary_key
    WHERE t2.primary_key IS NULL

    Это должно без проблем отображаться на синтаксис фреймворка.
    Ответ написан
  • Как выбрать только те записи, которые не пересекаются и только те, которые пересеклись?

    @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.
    Ответ написан
    Комментировать
  • Как производить переиндексацию в таблице SQLite?

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

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

    Обрати особое внимание - в течение времени жизни именно таблицы. Не записи! То есть то, что запись удалена, ни на что не влияет - отсутствующее значение первичного индекса идентифицирует факт, что запись существовала, но была удалена.

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

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

    Присваивайте нужное значение явно.
    Ответ написан
    3 комментария
  • Возможно ли составить такой SQL запрос?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Ничто не мешает использовать оконный вариант агрегатных функций. Кроме слишком старой версии СУБД, не поддерживающей оконные функции, конечно.
    SELECT MIN(`min_price`) OVER () as `min_price`, 
           MAX(`max_price`) OVER () as `max_price`, 
           `item_id` as `id`
    FROM `product_table` 
    WHERE `id` IN (SELECT  тут запрос)

    Получишь все нужные id, и в каждой строке - нужные MIN и MAX.

    ======================


    Akina, да, версия 5.7.21 и она, я так понимаю, не поддерживает оконные функции.


    SELECT t2.min_price, 
           t2.max_price, 
           t1.item_id as id
    FROM product_table t1
    CROSS JOIN ( SELECT MIN(min_price) AS min_price, 
                 MAX(max_price) AS max_price
                 FROM product_table ) t2
    WHERE t1.id IN (SELECT  тут запрос)
    Ответ написан
  • Возможно ли создать отчёт Excel с помощью SQL?

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

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT CASE WHEN sender_id = 1
                THEN receiver_id
                ELSE sender_id 
                END AS buddy
    FROM message
    WHERE 1 IN (sender_id, receiver_id)
    GROUP BY buddy
    ORDER BY MAX(sent_at)


    Ну и соответственно
    SELECT user.username
    FROM user
    JOIN ( SELECT CASE WHEN sender_id = 1
                       THEN receiver_id
                       ELSE sender_id 
                       END AS id,
                  MAX(sent_at) sent_at
           FROM message
           WHERE 1 IN (sender_id, receiver_id)
           GROUP BY 1 ) ids USING (id)
    ORDER BY ids.sent_at
    Ответ написан
    3 комментария
  • Как задать связи разного вида с помощью Foreign key?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Любой внешний ключ (FOREIGN KEY в структуре таблицы) задаёт связь типа 1:N (если локальное выражение внешнего ключа не может быть NULL) либо (0-1):N.

    Задание связи 1:1 (и соответственно (0-1):1) требует дополнительного ограничения уникальности на локальной стороне.

    Задание связи M:N требует дополнительной связующей таблицы.

    В данном случае "задание связи" == "создание правила контроля целостности и непротиворечивости данных, контролируемое на стороне сервера соответствующей подсистемой".
    Ответ написан
    Комментировать
  • Postgre Sql DISTINCT массив с ORDER BY?

    @Akina
    Сетевой и системный админ, SQL-программист.
    DISTINCT - это фактически частная форма GROUP BY. А потому к ней относятся все ограничения для GROUP BY в части использования полей источника данных в оконных функциях, выражениях пост-отбора и сортировки.

    Посему используйте поле выходного набора для сортировки.
    SELECT DISTINCT (regexp_split_to_array(commend, E'\\s+'))[:3] AS first_3_words
    FROM orders 
    ORDER BY first_3_words[2];
    Ответ написан
  • Как написать SQL запрос для среза непустых значений?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Общее решение:
    SELECT DISTINCT
           key,
           FIRST_VALUE(value1) OVER (PARTITION BY key 
                                     ORDER BY CASE WHEN value1 IS NULL 
                                                   THEN 1 
                                                   ELSE 0 END, id DESC) AS value1,
           FIRST_VALUE(value2) OVER (PARTITION BY key 
                                     ORDER BY CASE WHEN value2 IS NULL 
                                                   THEN 1 
                                                   ELSE 0 END, id DESC) AS value2,
           FIRST_VALUE(value3) OVER (PARTITION BY key 
                                     ORDER BY CASE WHEN value3 IS NULL 
                                                   THEN 1 
                                                   ELSE 0 END, id DESC) AS value3
    FROM tablename
    -- WHERE key IN ( {список значений} )


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

    @Akina
    Сетевой и системный админ, SQL-программист.
    Каждый сам творец своего геморроя.

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

    Под понятием "таблица" следует понимать строго один экземпляр исходного набора данных. Иными словами, запрос, в котором используется две копии одной таблицы, либо используется дополнительная синтетическая таблица констант, запросом с источником данных из одной таблицы не является.

    ---

    В некоторых диалектах указание алиаса может быть обязательно и по причине интерференции имён из разных пространств.

    Например, в хранимых объектах MySQL при совпадении имени поля таблицы с именем локальной переменной обращение без указания алиаса - это всегда обращение к переменной. Поэтому для MySQL правило ещё строже - алиас указывай всегда.

    И даже такая строгость порой недостаточна. Пример. Обратите внимание на сортировку - в ней id интерпретируется как имя переменной, а не имя поля выходного набора, и потому результат "странный". Кстати, это тот случай, когда вообще ничто не поможет, кроме использования выражения выходного поля вместо его имени.
    Ответ написан
    Комментировать
  • Как создать скрипт для получения данных из sql БД?

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

    Так что создаём Event Procedure, которая выгружает результат нужного запроса в файл в нужном формате, запускаем Event Scheduler... и всё.
    Ответ написан
    Комментировать
  • Как связать много сущностей к одной в результате?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT for_output
    FROM ( SELECT name AS film_name, name AS for_output
           FROM films
         UNION ALL
           SELECT films.name, comments.comment
           FROM films 
           JOIN comments USING (film_id) ) total
    ORDER BY film_name, film_name <> for_output
    Ответ написан
    Комментировать
  • Как сделать вложенность в json через SQL запрос?

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

    В общем, вложенные подзапросы либо цепь CTE, каждый со своим уровнем агрегирования.
    Ответ написан
    1 комментарий
  • Как правильно составить sql запрос с условием?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Схематично:
    SELECT orders.column,
           COALESCE(books.column, deposits.column) AS column
    FROM orders 
    LEFT JOIN books ON orders.type = 'book' AND orders.id = books.order_id
    LEFT JOIN deposits ON orders.type = 'deposit' AND orders.id = deposits.order_id
    Ответ написан
    1 комментарий
  • Показать все значения где другое значение count > 1?

    @Akina
    Сетевой и системный админ, SQL-программист.
    call_id, где есть больше одного значение value

    SELECT call_id
    FROM tablename
    GROUP BY call_id
    HAVING COUNT(DISTINCT value) > 1
    Ответ написан
    Комментировать