Задать вопрос
Ответы пользователя по тегу PostgreSQL
  • Изменение заглавных полей в постгрессе?

    @Akina
    Сетевой и системный админ, SQL-программист.
    PostgreSQL: Identifiers and Key Words
    MySQL: Identifier Case Sensitivity
    Прочитать и изучить ОЧЕНЬ внимательно - от этих ссылок и всё вокруг. Особое внимание - различиям между квотированными и неквотированными идентификаторами.

    Данные импортируются с названием колонок заглавными буквами.

    Ну, значит, так импортируешь. По-любому, это твой косяк.
    Ответ написан
    Комментировать
  • Как можно по триггеру отправлять данные из PostgreSQL в Redash?

    @Akina
    Сетевой и системный админ, SQL-программист.
    NOTIFY
    LISTEN
    Хотя как по мне, один запрос в 10 минут - это ни о чём.
    Ответ написан
    Комментировать
  • Как циклически пройтись по всем столбцам NEW?

    @Akina
    Сетевой и системный админ, SQL-программист.
    А не надо ничего хардкодить. И в INFORMATION_SCHEMA лезть тоже необязательно. Берём да используем row_to_json(NEW), и вся структура как на ладошке.

    Пример

    Получить массив/роусет ключей/значений и пробежаться по нему в цикле - уже не проблема.
    Ответ написан
    2 комментария
  • Почему с фильтром PostgreSQL выдаёт больше записей?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Если у клиента ВСЕ записи ранее текущего года НЕ соответствуют условию WHERE, то эти записи будут отброшены ещё до группировки. И клиент попадёт в выборку, потому что останутся только записи текущего года. Проверять надо после группировки:
    HAVING MAX(   (apps.in_trash is not true 
               and apps.status = 4 
               and apps.filial_id = 1 
               and apps.invoice_id is not null
                   ) :: INT
               ) > 0
    Ответ написан
    Комментировать
  • Как использовать оконные функции в Order By?

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

    С одной стороны, описание окна расположено в правильном месте - строго после HAVING clause (или того места, где бы оно находилось).

    С другой стороны, написан какой-то бред. Что должно означать ORDER BY w? Сортировка по определению окна? Вы же сами приводите правильную цитату:

    Оконные функции разрешается использовать в запросе только в списке SELECT и предложении ORDER BY.


    Где же у вас, собственно говоря, функция?

    Должно быть, ну, скажем, так:
    SELECT sum(num) OVER w 
    FROM my_table 
    WINDOW w AS (PARTITION BY name) 
    ORDER BY MAX(num) OVER w
    Ответ написан
    Комментировать
  • Как удалить строку из одной таблицы и добавить эту же строку в другую таблицу?

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

    В PostgreSQL это вообще элементарная операция. Можно удалить запись в CTE и вставить её во внешнем запросе, можно наоборот. То, как выполнять, определяется возможными зависимостями и интерференциями.
    WITH cte AS (
        DELETE
        FROM table1
        WHERE {criteria}
        RETURNING *
    )
    INSERT 
    INTO table2
    SELECT *
    FROM cte;
    
    -- или 
    
    WITH cte AS (
        INSERT 
        INTO table2
        SELECT *
        FROM table1
        WHERE {criteria}
        RETURNING id
    )
    DELETE
    FROM table1
    WHERE id IN (
        SELECT id
        FROM cte
    );

    Sample fiddle

    Само собой, вместо звёзд может быть (даже правильнее сказать - должен быть) перечень определённых полей и выражений.

    PS. Хотя намного разумнее оставить одну таблицу и выполнять "мягкое удаление". Внимательнейшим образом прочитайте ответ alexalexes. При очень большом количестве записей, влияющем на производительность, такую таблицу можно и секционировать.
    Ответ написан
    Комментировать
  • Как проранжировать данные таким образом, чтобы не менялся номер по определенному условию?

    @Akina
    Сетевой и системный админ, SQL-программист.
    WITH cte AS (
      SELECT *,
             SUM((flag IS NULL) :: INT) OVER (PARTITION BY user_id ORDER BY product_id ASC) grp
      FROM test
      )
    SELECT product_id, user_id, flag,
           DENSE_RANK() OVER (PARTITION BY user_id ORDER BY grp ASC) "rank"
    FROM cte
    ORDER BY 1,2;

    fiddle
    Ответ написан
    2 комментария
  • Как обновить столбец таблицы учитывая агрегатные функции?

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

    "Итог" numeric GENERATED ALWAYS AS ( COALESCE("Январь", 0) + 
                                         COALESCE("Февраль", 0) + 
                                         COALESCE("Март", 0) + 
                                         COALESCE("Апрель", 0) + 
                                         COALESCE("Май", 0) + 
                                         COALESCE("Июнь", 0) + 
                                         COALESCE("Июль", 0) + 
                                         COALESCE("Август", 0) + 
                                         COALESCE("Сентябрь", 0) + 
                                         COALESCE("Октябрь", 0) + 
                                         COALESCE("Ноябрь", 0) + 
                                         COALESCE("Декабрь", 0) ) STORED


    fiddle

    И запросов вообще никаких не нужно.

    PS. Но вообще такая форма хранения находится в вопиющем противоречии с нормальными формами. Настоятельно рекомендую переделать, пока не поздно.
    Ответ написан
    2 комментария
  • Как правильно сделать приписку со склонением слов в PostgreSQL?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT amount || ' ' ||
           CASE WHEN amount % 100 / 10 = 1 THEN 'автомобилей'
                WHEN amount % 10 = 1 THEN 'автомобиль'
                WHEN amount % 10 IN (2,3,4) THEN 'автомобиля'
                ELSE 'автомобилей'
                END
    FROM generate_series(0,600) AS source (amount)

    fiddle
    Ответ написан
    Комментировать
  • 10к строк по базе размером 500кк?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Запрос
    SELECT * FROM base WHERE domain LIKE '%habr%' LIMIT 10000;


    Какой это нахрен поиск "по совпадениям"??? Это, блин, поиск по подстроке!!! причём в любом месте строки.

    С таким шаблоном поиска можете с обычными индексами вообще не трахаться, по причине абсолютной бессмысленности действа. Читайте про GIN, GiST, RUM и прочие виды индексов и поиск с их использованием.
    Ответ написан
    Комментировать
  • Как составить правильный запрос к бд?

    @Akina
    Сетевой и системный админ, SQL-программист.
    ...
    HAVING COUNT(*) > 1
       AND SUM( (name IN ('зеленый', 'красный')) :: INT ) = 1
    Ответ написан
    1 комментарий
  • Как оконнной функцией вытащить последнее значение для предыдущего года?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Будет что-то вроде
    SELECT *,
           ( SELECT value
             FROM tablename t2
             WHERE t1.year - 1 = t2.year
             ORDER BY created_at DESC LIMIT 1 
             ) AS prev_value
    FROM tablename t1;
    Ответ написан
    2 комментария
  • Как показать 'соседние' записи?

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

    WITH cte AS (
        SELECT *, ROW_NUMBER() OVER (ORDER BY id) rn
        FROM tablename
        WHERE type = @type
        )
    SELECT /* DISTINCT */ t2.*
    FROM cte t1
    JOIN cte t2 ON t2.rn IN (t1.rn - 1, t1.rn, t1.rn + 1)
    WHERE t1.status = @status
    ORDER BY t2.rn
    Ответ написан
    Комментировать
  • Каким образом к существующей таблице можно добавить еще одну колонку для мультиязычности и добавить уже текст с переводом?

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


    Ага... а потом захочется на немецкий, на китайский... так и будешь поля добавлять?

    Классический подход - таблица текстовых литералов

    CREATE TABLE translation (
        token_id INT,      -- идентификатор строки
        language_id INT,   -- идентификатор языка
        PRIMARY KEY (token_id, language_id),
        value VARCHAR(100) NULL DEFAULT NULL
        );


    Соответственно зная номер строки, который нужен, и язык, получаем значение
    SELECT value
    FROM translation
    JOIN language USING (language_id)
    WHERE token_id = @token_id
      AND language_name = @language_name;

    Впрочем, обычное состояние - это когда не все строки переведены. Тогда используется
    SELECT COALESCE((
        SELECT value
        FROM translation
        JOIN language USING (language_id)
        WHERE token_id = @token_id
          AND language_name = @language_name;
        ), (
        SELECT value
        FROM translation
        JOIN language USING (language_id)
        WHERE token_id = @token_id
          AND language_name = @default_language_name;
        )) value;

    То есть для литералов. имеющих перевод, возвращаются именно они, а для ещё не имеющих - значение на языке по умолчанию.

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

    С другой стороны, вывод сообщений на экран - это интерактивное взаимодействие, где начхать на производительность. А коли так, то сообщения можно хранить в одном поле в виде JSON объекта, типа
    {
        "ru":"Выход",
        "en":"Quit"
    }

    Но и для такой схемы получение литерала для дефолтного языка при отсутствии перевода - актуально.
    Ответ написан
    Комментировать
  • Можно ли корректно заполнить создаваемое поле таблицы данными из другой таблицы?

    @Akina
    Сетевой и системный админ, SQL-программист.
    UPDATE TableA 
    SET tableB_Id = TableB.Id
    FROM TableB
    WHERE TableA.Name = TableB.Name;


    fiddle
    Ответ написан
    Комментировать
  • Как гарантировать последовательную запись данных без пропусков id?

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


    Никак НЕ РЕАЛИЗОВЫВАТЬ.

    Оставь автоинкремент в покое - он обязан обеспечивать только уникальность, и не более. Нужна непрерывная нумерация? Создай для неё ОТДЕЛЬНОЕ поле, и нумеруй программно. Триггеры в помощь.
    Ответ написан
    4 комментария
  • Какой проект можно сделать на PL/pgSQL новичку?

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

    ИМХО

    PL/pgSQL, T-SQL и прочие аналогичные языки в первую очередь предназначены для создания систем, в которых интенсивно используется server-side логика. Ибо возможности и инструментарий такого языка кроет (установленные стандартом) возможности SQL как бык овцу...

    А всё остальное - это винтики-бантики.

    Если кто-то набросает какой-нибудь PL/pgSQL код в любом фиддле, для иллюстрации что на нем можно делать - буду премного благодарен.

    Открываешь документацию по Постгрессу, забиваешь в поиск LANGUAGE plpgsql и получаешь кучу ссылок с примерами кодов. А если это будет документация по ПостгрессПро - так ещё и по-русски.
    Ответ написан
    3 комментария
  • Как создать процедуру, которая будет возвращать что-то?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Процедуры, в отличие от функций, не возвращают значение; поэтому в CREATE PROCEDURE отсутствует предложение RETURNS. Однако процедуры могут выдавать данные в вызывающий код через выходные параметры.

    https://postgrespro.ru/docs/postgresql/16/xproc (имеются в виду SQL-процедуры)

    Для возврата значений из PL/pgSQL процедуры используются OUT и INOUT параметры.

    https://postgrespro.ru/docs/postgresql/16/plpgsql-... (пример имеется)
    Ответ написан
    Комментировать
  • Почему один запрос работает, а другой нет?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Оператор ?| в PostgreSQL выполняет поиск строковых значений в списке элементов массива или ключей (имён атрибутов) объекта:

    jsonb ?| text[] → boolean

    Do any of the strings in the text array exist as top-level keys or array elements?

    '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd'] → t

    https://www.postgresql.org/docs/current/functions-...

    В PostgreSQL нет встроенных функции или оператора для указанной задачи или для проверки на пересечение двух числовых JSON массивов. Возможное решение - разобрать JSON-массив на элементы, собрать в обычный массив и использовать для двух массивов оператор &&
    Ответ написан
  • Как получить количество первичных записей в таблице?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Если принять такую формулировку:

    Первичным является товар, одновременно с которым куплено больше всего других товаров

    то запрос на получение "первичных" товаров будет такой:

    WITH cte AS (
        SELECT t1.cat_id, RANK() OVER (ORDER BY COUNT(t2.cat_id) DESC) rnk
        FROM user_to_cat t1
        JOIN user_to_cat t2 ON t1.user_id = t2.user_id
                           AND t1.cat_id <> t2.cat_id
        GROUP BY 1
        )
    SELECT category.code
    FROM cte
    JOIN category ON category.id = cte.cat_id
    WHERE rnk = 1

    На данных из fiddle запрос даст 2 товара - orange и pear, оба они участвуют в 6 парах, тогда как apple участвуют в 4, а lemon в 2 парах.
    Ответ написан