简体   繁体   English

Postgres:GROUP BY几栏

[英]Postgres: GROUP BY several column

I have two table in this example. 我在这个例子中有两个表。

( example column name ) (示例列名称)

First is the product 首先是产品

product_id | product_text

Second table is Price. 第二个表是Price。

price_productid | price_datestart | price_price

Let's just say I have multiple datestart with the same product. 我们只想说我有同一产品的多个日期启动。 How can I get the actual price ? 我怎样才能得到实际价格?

If I use GROUP BY in Postgres, with all the selected column, 2 row may come for the same product. 如果我在Postgres中使用GROUP BY,并且所有选定列都可以使用同一产品的2行。 Because the column price_datestart is different. 因为列price_datestart是不同的。

Example : 示例:

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"

If I try this : 如果我试试这个:

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

It will give me a result, but two rows and I need one. 它会给我一个结果,但是两行我需要一个。

Use distinct on syntax. distinct on语法distinct on使用distinct on If you want current price: 如果您想要当前价格:

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 sql小提琴演示

You have a few problems, but GROUP BY is not one of them. 你有一些问题,但GROUP BY不是其中之一。

First, although you have a datestart you don't have a dateend. 首先,虽然您有一个日期启动,但您没有日期。 I'd change datestart to be a daterange, for example: 我将datestart更改为日期范围,例如:

CREATE TABLE product
( 
  product_id int
 ,product_text text
);

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

The TSRANGE allows you to set up validity of your price over a given range, for example: 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);

And that makes your SELECT much more simple, for example: 这使得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

This also has the benefit of allowing you to query for any arbitrary time by swapping out now() for another date. 这也有一个好处,允许您通过将now()换成另一个日期来查询任意时间。

You should read up on ranges in PostgresQL as they are very powerful. 你应该阅读PostgresQL中的范围,因为它们非常强大。 The example above is not complete in that it should also have indices on price_daterange to ensure that you do not have overlaps for any product. 上面的示例并不完整,因为它还应该在price_daterange上有索引,以确保您没有任何产品的重叠。

SQL fiddle with above solution SQL摆弄上述解决方案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM