Задать вопрос
Ответы пользователя по тегу PostgreSQL
  • Как сделать поиск определенного значение в строке отобранной SELECT * FROM?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Что-нибудь типа
    SELECT *
    FROM archiv,
         json_each(row_to_json(archiv))
    WHERE json_each.value :: text LIKE '%10%'
      AND json_each.key <> 'id'
      /* AND условия по таблице archiv */;

    fiddle
    Ответ написан
  • Как получить данные и обновить записи в таблицах-источниках?

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

    Это совершенно нормальная практика в Постгрессе. Более того, она предпочтительнее любой другой техники с кучей запросов и транзакцией, потому как гарантирует полную согласованность всех изменений и минимизирует количество интерференций и блокировок. Ну и не злоупотребляйте отложенными (DEFERRED) проверками - они, конечно, ускоряют, но будет обидно сделать всё, и лишь при финальном контроле свалиться по ошибке проверки.

    Хотя именно для показанного шаблона (один UPDATE, и нужно получить обновлённые записи) я не понимаю, почему просто не сделать финальный апдейт внешним запросом с использованием кляузы RETURNING. Ваш финальный select * from result смотрится совершенно бессмысленной нашлёпкой.
    Ответ написан
  • Как отредактировать строку в таблице, не имеющей primary key?

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

    Значит, используйте SQL-запрос. И повнимательнее - чтобы количество ошибок при выполнении запроса не увеличилось...

    таблица не имеет primary key

    Создайте в таблице первичный ключ. Лучше синтетический.
    С другой стороны, вы пишете:

    отредактировать строки, связанные с этим пользователем

    Если есть связанные записи - значит, есть внешние ключи и соответственно как минимум уникальные индексы. Что-то как-то не бьётся...

    По ошибке добавили сотрудницу в базу ... не обратили внимания, что такая запись в таблице уже существует

    Создайте соответствующие ограничения (UNIQUE index) в структуре.

    Мне бы не хотелось менять структуру таблицы

    А регулярно купаться в дерьме - хотелось бы? Хотите спокойно спать - отставьте свои хотелки в сторону и сделайте так, чтобы проблем, подобных описанной, не могло произойти в принципе.
    Ответ написан
    5 комментариев
  • Как отработать EXTRACT(epoch FROM MAX(null))?

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

    Вотще! Это забота программиста - обеспечить корректное значения параметра.
    SELECT EXTRACT(epoch FROM COALESCE( MAX(t.date_x), {default datetime literal} )) 
    FROM T

    Если очень надо- можно ещё сверху NULLIF() наслоить.

    Альтернативное решение - явное приведение типа:
    SELECT EXTRACT(epoch FROM CAST( MAX(t.date_x) AS TIMESTAMP)) 
    FROM T
    Ответ написан
  • Изменение заглавных полей в постгрессе?

    @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 комментария