Postgres:GROUP BY几栏

时间:2013-09-19 09:33:56

标签: sql postgresql group-by

我在这个例子中有两张表。

(示例列名称)

首先是产品

product_id | product_text

第二张表是Price。

price_productid | price_datestart | price_price

我们只想说我有同一产品的多个日期启动。我怎样才能得到实际价格?

如果我在Postgres中使用GROUP BY,并且所有选定的列都可以使用同一产品的2行。因为列price_datestart不同。

示例:

product_id : 1
product_text : "Apple Iphone"


price_productid : 1
price_datestart :"2013-10-01"
price_price :"99"


price_productid : 1
price_datestart :"2013-12-01"
price_price :"75"

如果我试试这个:

SELECT price_productid,price_datestart,price_price,product_text,product_id
WHERE price_datestart > now()
GROUP BY price_productid,price_datestart,price_price,product_text,product_id
ORDER BY price_datestart ASC

它会给我一个结果,但是我需要两行。

2 个答案:

答案 0 :(得分:3)

使用distinct on语法。如果您想要当前价格:

select distinct on (p.productid)
    p.productid, pr.product_text, p.price, p.datestart
from Price as p
    left outer join Product as pr on pr.productid = p.productid
where p.datestart <= now()
order by p.productid, p.datestart desc

<强> sql fiddle demo

答案 1 :(得分:0)

你有一些问题,但GROUP BY不是其中之一。

首先,虽然您有一个日期启动,但您没有日期。我将datestart更改为日期范围,例如:

CREATE TABLE product
( 
  product_id int
 ,product_text text
);

CREATE TABLE price
(
  price_productid int
 ,price_daterange TSRANGE
 ,price_price     NUMERIC(10,2)
);

TSRANGE允许您在给定范围内设置价格的有效性,例如:

INSERT INTO product VALUES(1, 'phone');
INSERT INTO price VALUES(1, '[2013-08-01 00:00:00,2013-10-01 00:00:00)', 199);
INSERT INTO price VALUES(1, '[2013-10-01 00:00:00,2013-12-01 00:00:00)', 99);
INSERT INTO price VALUES(1, '[2013-12-01 00:00:00,)', 75);

这使您的SELECT变得更加简单,例如:

SELECT price_productid,price_daterange,price_price,product_text,product_id
FROM product, price
WHERE price_daterange @> now()::timestamp
AND product_id = price_productid

这样做的好处是,您可以通过将now()换成另一个日期来查询任意时间。

你应该阅读PostgresQL中的范围,因为它们非常强大。上面的示例并不完整,因为它还应该在price_daterange上设置索引,以确保您没有任何产品的重叠。

SQL fiddle with above solution