3

この例には 2 つのテーブルがあります。

(例 カラム名)

まずは商品です

product_id | product_text

2 番目のテーブルは価格です。

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行で1行が必要です。

4

2 に答える 2

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

于 2013-09-19T09:46:42.923 に答える
0

いくつか問題がありますが、GROUP BY はその 1 つではありません。

まず、datestart がありますが、dateend がありません。たとえば、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フィドル

于 2013-09-19T09:55:45.740 に答える