Сгруппируйте по году и месяцу и получите минимальное значение за месяц с указанием даты - PullRequest
0 голосов
/ 06 ноября 2018

Вот так выглядит мой стол

Column  |     Type     |
--------+--------------+
id      | integer      |
date    | date         |
open    | numeric(9,2) |
close   | numeric(9,2) |
low     | numeric(9,2) |
high    | numeric(9,2) |

Я бы хотел получить дату наименьшего значения закрытия для данного месяца за все месяцы.

Это то, что мне удалось получить,

SELECT 
    temp_table.year, temp_table.month, MIN(close)
FROM
    (
        SELECT 
            date_trunc('year', date) as year, date_trunc('month', date) as month, date, close 
        FROM
            sensex_sensex
        GROUP BY 
            year, month, date, close
        ORDER BY 
            year, month
    ) AS temp_table
GROUP BY
    temp_table.year, temp_table.month
ORDER BY
    temp_table.year DESC, temp_table.month DESC;

Это дает мне год и наименьшее значение закрытия. Но когда я пытаюсь добавить дату, я получаю все строки вместо того, чтобы группировать их по годам и месяцам. Как мне получить результат как

Year | Month | Date of Lowest Close in a Month | Lowest Close in a Month

Также дополнительно,

Я также хотел бы найти как минимум 5 близких значений за месяц с их датами, снова сгруппированными по году и месяцу.

Ответы [ 3 ]

0 голосов
/ 06 ноября 2018

использовать подзапрос с поддержкой Corelted

SELECT 
  date_trunc('year', date) as year, date_trunc('month', date) as month, date, close 
            FROM
                sensex_sensex t where t.close=( select min(close)
                                    from 
                                   sensex_sensex t1
  where   date_trunc('year', t1.date)=date_trunc('year', t.date)
    and
     date_trunc('month', t1.date)=date_trunc('month', t.date)
 )

Или используйте оконную функцию

with cte (   
    select  
         date_trunc('year', date) as year,
         date_trunc('month', date) as month, date, close,
         min (close) over ( order by date ) rn 
    FROM
         sensex_sensex
) select * from cte where cte.rn=1
0 голосов
/ 06 ноября 2018

демо: дб <> скрипка

Используя оконную функцию MIN выбирает минимальное значение для кадра (в вашем случае месяц).

SELECT
    extract('year' FROM mydate) as year,
    extract('month' FROM mydate) as month,
    mydate, close
FROM (
    SELECT
        mydate,
        close,
        MIN(close) OVER (PARTITION BY date_trunc('month', mydate)) as min_close
    FROM
        temp_table
) s
WHERE close = min_close

Вместо MIN вы можете использовать ROW_NUMBER. Это поможет вам, если вы хотите выбрать не только один минимум, но и два или пять наименьших чисел (n):

SELECT
    extract('year' FROM mydate) as year,
    extract('month' FROM mydate) as month,
    mydate, close
FROM (
    SELECT
        mydate,
        close,
        ROW_NUMBER() OVER (PARTITION BY date_trunc('month', mydate) ORDER BY close) as rn
    FROM
        temp_table
) s
WHERE rn <= n              -- n is the number of values you get.

Вам действительно нужны отдельные столбцы для года и месяца, которые можно легко рассчитать по дате?

0 голосов
/ 06 ноября 2018

Вы можете использовать коррелированный подзапрос

     SELECT date_trunc('year', date) as year, date_trunc('month', date) as month, date, close 
     FROM sensex_sensex a where close in 
    (select min(close) from sensex_sensex b 
     where date_trunc('year', a.date)=date_trunc('year', b.date) 
     and date_trunc('month', a.date)=date_trunc('month', b.date))

ИЛИ вы можете использовать функцию окна row_number ()

select * from
(
SELECT date_trunc('year', date) as year, date_trunc('month', date) as month, date, close,row_number() over(partition by date_trunc('year', date),date_trunc('month', date) order by close) as rn
         FROM sensex_sensex
)A where rn=1
...