2016-09-26 2 views
0

У меня есть база данных, которая параллельна базе данных «widget» ниже.GROUP BY PostgreSQL запрос, где мне нужен столбец, который не находится в предложении GROUP BY

widget_id | vendor_id | price 
------------------------------ 
    1  | 101 | 10.00 
    2  | 101 | 9.00 
    3  | 102 | 6.00 
    4  | 102 | 7.00 

Я хочу найти самый дешевый виджет на поставщика, так что-то вроде ниже выхода:

widget_id | vendor_id | price 
------------------------------ 
    1  | 101 | 10.00 
    3  | 102 | 6.00 

В MySQL или SQLite, я мог бы запросить

SELECT widget_id, vendor_id, min(price) AS price FROM widgets GROUP BY(vendor_id) 

Тем не менее, кажется, что это противоречит спецификации SQL. В PostgreSQL я не могу выполнить указанный выше запрос. Сообщение об ошибке «widget_id должно появиться в предложении GROUP BY или использоваться в агрегатной функции». Я могу видеть точку PostgreSQL, но, похоже, совершенно разумно хотеть, чтобы widget_id виджета имел минимальную цену.

Что я делаю неправильно?

+1

Неверный код в MySQL и SQLite. Не гарантируется возврат правильного результата. –

ответ

1

Вы можете использовать DISTINCT ON:

SELECT DISTINCT ON (vendor_id) * 
FROM widget 
ORDER BY vendor_id, price; 

Вы также можете использовать функцию row_number окна в подзапрос:

SELECT widget_id, vendor_id, price 
FROM (
    SELECT *, row_number() OVER (PARTITION BY vendor_id ORDER BY price) AS rn 
    FROM widget 
) t 
WHERE rn=1; 

Финлей, вы также можете сделать это с LATERAL присоединиться:

SELECT t2.* 
FROM 
    (SELECT DISTINCT vendor_id FROM widget) t1, 
    LATERAL (SELECT * FROM widget WHERE vendor_id=t1.vendor_id ORDER BY price LIMIT 1) t2