我正在努力创建一个涉及使用PostgreSQL聚合的SQL查询。请考虑以下表格:
CREATE TABLE thing (
id INT NOT NULL PRIMARY KEY,
price NUMERIC(10,2) NOT NULL,
description VARCHAR(255) NOT NULL,
url VARCHAR(255) NOT NULL,
location_id INT NOT NULL REFERENCES location(id)
)
CREATE TABLE location (
id INT NOT NULL PRIMARY KEY,
type INT NOT NULL,
name VARCHAR(255) NOT NULL
)
现在,我想获得每个位置的所有记录,其中location.type = xxx具有最低价格。
类似的东西:
SELECT min(price) FROM thing
INNER JOIN location ON (thing.location_id = location.id)
WHERE type = xxx
GROUP BY location_id
这将列出xxx类型的每个位置的最低价格,但是如何从表格中获取这些列的行(或它们的主键)?
答案 0 :(得分:5)
使用此PostgreSQL
扩展程序:
SELECT DISTINCT ON (location.id) thing.*
FROM location
JOIN thing
ON thing.location_id = location_id
WHERE type = 1
ORDER BY
location.id ASC, price ASC
这将仅选择每个location.id
的第一行。
由于您的行按location.id
排序,然后按price
排序,因此这将是最低价格的行。
在新的PostgreSQL 8.4
中,您还可以使用窗口函数:
SELECT *
FROM (
SELECT thing.*, ROW_NUMBER() OVER (PARTITION BY location_id ORDER BY price) AS rn
FROM location
JOIN thing
ON thing.location_id = location_id
WHERE type = 1
) q
WHERE rn = 1
答案 1 :(得分:0)
也许使用子查询
SELECT t.id,t.description,t.price FROM
( SELECT location_id, min(price) FROM thing
INNER JOIN location ON (thing.location_id = location.id)
WHERE type = xxx
GROUP BY location_id
) AS lowest
INNER JOIN thing AS t
ON t. location_id = lowest.location_id;
答案 2 :(得分:0)
我是SQL Server的人,但以下内容应该符合SQL-92并且应该可以工作:
select th.*
from thing th
inner join (select lo.id, min(th.price) minPrice
from location lo
inner join thing th
on th.location_id = lo.id
where lo.type = xxx
group by lo.id) minSet
on minSet.id = th.location_id
and th.price = minSet.minPrice
另请注意,我没有设置表格进行测试,因此可能会有一两个错字。
虽然它确实有效但确实看起来很尴尬。如果Postgres有类似SQL的排名函数,它们会让它变得更简单。
答案 3 :(得分:0)
尝试此查询
select thing.id,thing.description,thing.url,low.location_id,low.minimum from
(select thing.location_id,min(price) as minimum from thing
join location on thing.location_id=location.id
where location.type = 13 group by location_id) as low
inner join thing on thing.location_id = low.location_id