Хобрук: Ваш путь к мастерству в программировании

Получить максимальные значения в PostgreSQL 8.0

Я использую Amazon Redshift. Мне нужно получить дату MAX в столбце по месяцам. Пример приведен ниже.

Есть 5 столов:

vendor
vendor_pkg
vendor_pkg_category
vendor_load
vendor_load_status

vendor  V

vendor_id   vendor_name
-----------------------
1            L&T
2            Reuters
3            IBM
4            INfosys

vendor_pkg  VP

vendor_pkg_id  vendor_pkg_category_id   vendor_pkg_name  vendor_id
------------------------------------------------------------------
1              1                        Futures          1
2              1                        Fairvalue        1
3              3                        Equities         1
4              2                        MBS              1
5              2                        INTL Price       2
6              4                        Muni             2

vendor_pkg_category  VPC

vendor_pkg_category_id  category_name
-------------------------------------
1                       Price
2                       Security
3                       Rating
4                       value

Vendor_load  VL

vendor_load_id  eval_date   load_status_id  vendor_pkg_id
---------------------------------------------------------
1               2014-06-05  1               1
2               2014-06-20  1               1
3               2014-07-05  2               2
4               2014-07-20  1               2
5               2014-06-05  2               3
6               2014-06-20  2               3
7               2014-07-05  1               4
8               2014-07-20  2               4

vendor_load_status  VLS

load_status_id  load_status_name
--------------------------------
1               Success
2               Failed

Таблица результатов должна быть такой:

v.vendor  vpc.category_name  vp.ven_pkg_name  vl.eval_date  vls.status_name
---------------------------------------------------------------------------
L&T       Price              futures          2014-06-20    Success
L&T       Price              fairvalue        2014-07-20    Success
L&T       Security           MBS              2014-07-20    Failed
L&T       Rating             Equities         2014-06-20    Failed

Я использую следующий запрос. Но он отображает данные только за один месяц:

SELECT DISTINCT v.vendor_name AS vendor,
       vpc.category_name AS V_Type,
       vp.vendor_pkg_name AS Package_name,
       vl.eval_date AS C_Date,
       vls.load_status_name AS Status
FROM ces_idw.vendor v,
     ces_idw.vendor_pkg_category vpc,
     ces_idw.vendor_load vl,
     ces_idw.vendor_pkg vp,
     ces_idw.vendor_load_status vls
WHERE (vl.eval_date) IN (SELECT DISTINCT MAX(vl.eval_date)
                         FROM ces_idw.vendor_load vl
                         WHERE v.vendor_id = vp.vendor_id
                         and v.vendor_name = 'IDC'
                         AND   vp.vendor_pkg_id = vl.vendor_pkg_id
                         AND   TO_CHAR(vl.eval_date,'yyyy-mm') = '2014-06'
                         GROUP BY vl.vendor_pkg_id,
                                  v.vendor_name)                               
AND   vp.vendor_pkg_category_id = vpc.vendor_pkg_category_id
AND   vp.vendor_pkg_id = vl.vendor_pkg_id
AND   vl.load_status_id = vls.load_status_id
ORDER BY vp.vendor_pkg_name

когда я использую TO_CHAR(vl.eval_date,'yyyy-mm')between '2014-06' and '2014-07', он показывает результат для '2014-07'.


  • В другом вопросе вы упоминаете, что это Redshift. Здесь вы отметили 9.1. Что это? 17.07.2014
  • извини мой друг, это моя ошибка. мне нужна помощь для этого запроса, поэтому я добавил 9.1. 17.07.2014
  • Кросс-пост: dba.stackexchange.com/questions/71753/ 17.07.2014
  • Предыдущий пост не детализирован, поэтому загрузил этот 17.07.2014
  • Открыт повторно, так как ОП удалил обман. 18.07.2014
  • Вы уверены, что используете древнюю версию 8.0? Если это так, обновите до текущей версии, если это вообще возможно. 18.07.2014
  • это в облаке. мы не можем обновить. 18.07.2014
  • Ни один облачный сервис не предлагает Postgres 8.0. Это настолько старо, что облако тогда еще даже не было изобретено. 18.07.2014
  • tmrw я загружу все подробности. кто-то просмотрит и ответит на него. 18.07.2014
  • кто-нибудь ответит на мой вопрос? 21.07.2014

Ответы:


1

В соответствии с вашими примерными данными я написал запрос, который дает вам упомянутый набор результатов.

DECLARE @exp table (ID INT,Name VARCHAR(10))
INSERT INTO @exp (ID,Name) VALUES (1,'PRICE')
INSERT INTO @exp (ID,Name) VALUES (2,'STOCK')
INSERT INTO @exp (ID,Name) VALUES (3,'INCOME')
INSERT INTO @exp (ID,Name) VALUES (4,'LOAD')
INSERT INTO @exp (ID,Name) VALUES (5,'INITIAL')

DECLARE @exp1 table (ID INT,PID INT,Name VARCHAR(10),Dated Date)
INSERT INTO @exp1 (ID,PID,Name,Dated) VALUES (1,1,'PRICE','2014-08-05')
INSERT INTO @exp1 (ID,PID,Name,Dated) VALUES (2,1,'PRICE','2014-08-09')
INSERT INTO @exp1 (ID,PID,Name,Dated) VALUES (3,2,'STOCK','2014-08-05')
INSERT INTO @exp1 (ID,PID,Name,Dated) VALUES (4,2,'STOCK','2014-08-05')
INSERT INTO @exp1 (ID,PID,Name,Dated) VALUES (5,3,'INCOME','2014-08-10')
INSERT INTO @exp1 (ID,PID,Name,Dated) VALUES (6,3,'INCOME','2014-08-20')
INSERT INTO @exp1 (ID,PID,Name,Dated) VALUES (7,4,'LOAD','2014-08-10')
INSERT INTO @exp1 (ID,PID,Name,Dated) VALUES (8,4,'LOAD','2014-08-19')
INSERT INTO @exp1 (ID,PID,Name,Dated) VALUES (9,5,'INITIAL','2014-08-05')
INSERT INTO @exp1 (ID,PID,Name,Dated) VALUES (10,5,'INITIAL','2014-08-05')

SELECT DISTINCT groupedtt.ID,groupedtt.PID,tt.Name,groupedtt.MaxDateTime
FROM @exp tt
INNER JOIN
    (SELECT ID,PId, MAX(dated) AS MaxDateTime,DENSE_RANK()OVER (PARTITION BY PID ORDER BY ID )RN
    FROM @exp1
    GROUP BY PId,ID) groupedtt 
ON tt.id = groupedtt.PId AND 
RN = 2
17.07.2014
  • одно сомнение. если я извлеку данные из еще одной таблицы, она будет извлечена. например, связь между t1 и t2 осуществляется посредством t3. 17.07.2014
  • да, мы можем написать еще одно внутреннее соединение для другой таблицы и получить требуемый результат, и многое другое зависит от структуры таблицы @benpep 17.07.2014
  • Это недопустимый синтаксис для Postgres 19.07.2014

  • 2

    Я нашел ответ на свой вопрос.

    SELECT DISTINCT v.vendor_name AS vendor,
           vpc.category_name AS V_Type,
           vp.vendor_pkg_name AS Package_name,
           vl.eval_date AS C_Date,
           vls.load_status_name AS Status
    FROM ces_idw.vendor v,
         ces_idw.vendor_pkg_category vpc,
         ces_idw.vendor_load vl,
         ces_idw.vendor_pkg vp,
         ces_idw.vendor_load_status vls
    WHERE  (vl.eval_date) IN (
                             SELECT DISTINCT MAX(vl.eval_date)
                             FROM  ces_idw.vendor_load vl
                             WHERE v.vendor_id = vp.vendor_id
                             AND   v.vendor_name = 'L&T'
                             AND   vp.vendor_pkg_id = vl.vendor_pkg_id
                             AND  (TO_CHAR(vl.eval_date,'yyyy-mm') between '2013-01' and '2015-12')
                             GROUP BY extract(month from vl.eval_date),vl.vendor_pkg_id, v.vendor_name
                             ) 
    AND   vp.vendor_pkg_category_id = vpc.vendor_pkg_category_id
    AND   vp.vendor_pkg_id = vl.vendor_pkg_id
    AND   vl.load_status_id = vls.load_status_id
    ORDER BY vp.vendor_pkg_name
    

    Спасибо всем

    23.07.2014

    3

    Ваше принятое в настоящее время решение кажется неверным.
    По моему обоснованному мнению, вам нужно:
    Подробности для последней строки за месяц для каждого продукта заданного поставщик.

    SELECT DISTINCT ON (v.vendor_id, vl.vendor_pkg_id
                      , date_trunc('month', vl.eval_date))
           v.vendor_name        AS vendor
         , vpc.category_name    AS v_type
         , vp.vendor_pkg_name   AS package_name
         , vl.eval_date         AS c_date
         , vls.load_status_name AS status
    FROM   ces_idw.vendor              v
    JOIN   ces_idw.vendor_pkg          vp  USING (vendor_id)
    JOIN   ces_idw.vendor_load         vl  USING (vendor_pkg_id)
    JOIN   ces_idw.vendor_load_status  vls USING (load_status_id)
    JOIN   ces_idw.vendor_pkg_category vpc USING (vendor_pkg_category_id)
    WHERE  v.vendor_name = 'L&T'
    AND    vl.eval_date BETWEEN '2013-01-01' AND '2015-12-31'
    ORDER  BY v.vendor_id, vl.vendor_pkg_id
            , date_trunc('month', vl.eval_date), vl.eval_date DESC;
    

    Основные моменты

    • Возвращает то, что я описал. Гораздо проще и быстрее, чем ваше текущее решение. И, вероятно, правильно.

    • Используйте явный JOIN синтаксис, это намного понятнее. Еще проще с USING< /strong>, что позволяет ваше соглашение об именах.

    • Используйте DISTINCT ON, доступно с .. навсегда в Postgres.
      date_trunc() вместо extract() разделяет все месяцы. Не имеет особого смысла группировать месяцы из нескольких лет вместе.
      Добавленный элемент vl.eval_date DESC в предложении ORDER BY выбирает последнюю строку месяца.
      Подробное объяснение DISTINCT ON:
      Выбрать первую строку в каждой группе GROUP BY?

    • Поскольку неясно, является ли vendor_name уникальным, я включил vendor_id в пункты DISTINCT ON и ORDER BY соответственно.

    • Не преобразовывайте столбец date в text в предложении WHERE, это дорогая ерунда и делает невозможным использование простых индексов. Полученное выражение не является sargable.

    • Не используйте многократно закрученный и дорогой подзапрос, связанный IN. Полностью заменено на DISTINCT ON.
      В частности, объединение DISTINCT с MAX(vl.eval_date) не имеет смысла.

    • Чтобы сделать это быстро, вам нужны только индексы для (Vendor_load.eval_date) и (vendor.vendor_name) в дополнение к очевидным первичным ключам и индексам для столбцов внешнего ключа.

    Все ссылки на руководство по Postgres 8.0.

    23.07.2014
  • Спасибо за ответ, но DISTINCT ON не работает в моем PostgreSQL. Вот почему я написал код, который я публикую. @Эрвин Брандштеттер 24.07.2014
  • @benpep: я предлагаю вам, наконец, объявить, с чем вы работаете, как вы должны были сделать с самого начала. Это красное смещение? Что вы получаете от SELECT version(). Отредактируйте вопрос с этой базовой информацией. 24.07.2014
  • да. это моя ошибка. это показывает. PostgreSQL 8.0.2 на i686-pc-linux-gnu, скомпилированный GCC gcc (GCC) 3.4.2 (Red Hat 3.4.2-6.fc3), Redshift 1.0.797 25.07.2014
  • Новые материалы

    Получение стоковых обновлений с помощью Python
    Для начинающего финансового аналитика Введение Описание: Этот проект Python создает скрипт для получения текущих обновлений акций с финансового веб-сайта Yahoo. Для этого проекта мы..

    Это все, что вам нужно знать о Kotlin в 2022 году
    Добро пожаловать! Kotlin — это язык программирования, популярность которого, кажется, растет, его действительно можно использовать для создания чего угодно, и если вы хотите узнать о Kotlin,..

    Текстовый графический интерфейс с Lanterna на Java
    Мой опыт работы с компьютерами (и текстовыми графическими пользовательскими интерфейсами) начался еще в восьмидесятых, когда я был ребенком, на дне рождения друга. Это был «новенький» Amstrad..

    Перезарядите свой мозг: умопомрачительный потенциал мозговых компьютерных интерфейсов
    Способность читать свои мысли и управлять объектами разумом долгое время были предметом человеческого любопытства, ограниченного областью научной фантастики… то есть до сих пор? С технологией,..

    Основы C# — Нулевой оператор объединения (??)
    Оператор ?? называется null-coalescing operator . Этот оператор используется для предоставления значения по умолчанию, если значение операнда в левой части оператора равно null ...

    Сравнение номеров версий в C++ с использованием синтаксического анализа строк
    Номера версий обычно используются для обозначения развития или обновлений программного обеспечения или любого другого продукта. При работе с номерами версий в C++ может быть полезно сравнить две..

    В мир искусственного интеллекта…
    ИИ — это новое топливо в современном мире. Куда бы вы ни обратились, с кем бы вы ни разговаривали — они, как правило, упоминают об ИИ хотя бы раз в ходе разговора. ИИ гудит повсюду. У каждого..


    © 2024 hobruk.ru, Хобрук: Ваш путь к мастерству в программировании