请帮我构建PostgreSQL查询。 有2个表:产品(ID,标题)和价格(id,product_id,price_type,时刻,价值)
时刻 - 时间戳,可以是过去或未来
假设price_type只有两个选项:零售或购买
但是,一种产品可能会有不同时刻的零售价格。
我需要选择所有具有实际零售价和购买价的产品,其中的时刻不到现在。
我可以做到
SELECT
products.id,
products.title_translations AS title,
retail_prices.moment AS ret_moment,
pur_prices.value AS purchase,
retail_prices.value AS retail
FROM products
LEFT OUTER JOIN prices AS pur_prices ON products.id=pur_prices.product_id AND pur_prices.price_type='purchase' AND pur_prices.moment<current_timestamp
LEFT OUTER JOIN prices AS retail_prices ON products.id=retail_prices.product_id AND retail_prices.price_type='retail' AND retail_prices.moment<current_timestamp
ORDER BY products.id;
它有效但返回 所有价格的产品,但我只需要最后的价格(按时)。
答案 0 :(得分:2)
只需使用ROW_NUMBER
查找当前时间之前的最后价格
with last_prices as (
SELECT
products.id,
products.title_translations AS title,
prices.moment,
prices.value,
prices.price_type,
ROW_NUMBER() OVER (PARTITION BY product_id, price_type
ORDER BY moment DESC) as rn
FROM products
LEFT JOIN prices
ON products.id = prices.product_id
WHERE moment < now()
)
SELECT id, title,
MAX(CASE WHEN price_type = 'retail'
THEN moment
END) as retail_moment,
MAX(CASE WHEN price_type = 'retail'
THEN value
END) as retail_price,
MAX(CASE WHEN price_type = 'purchase'
THEN moment
END) as purchase_moment,
MAX(CASE WHEN price_type = 'purchase'
THEN value
END) as purchase_price
FROM last_prices
WHERE rn = 1
GROUP BY id, title
ORDER BY id
答案 1 :(得分:2)
为了让事情井井有条,我会直接考虑,我会使用CTE生成两个价格数据子集,一个用于零售购买一个子集,并按升序排列一个行号,最小数量最多最近时刻小于currenttimestmap。然后当我们加入这些ctes时,我们只返回指定的最小数字。
With Pur_prices as (SELECT P.*, row_Number() over (partition by product_ID order by moment desc) RN
FROM prices P
WHERE price_Type = 'purchase'
and p.moment < current_timestamp)
, Retail_prices as (SELECT P.*, row_Number() over (partition by product_ID order by moment desc) RN
FROM prices P
WHERE price_Type = 'retail'
and p.moment < current_timestamp)
SELECT
p.id,
p.title_translations AS title,
rp.moment AS ret_moment,
rp.value AS retail,
pp.moment AS Pur_moment,
pp.value AS purchase
FROM products p
LEFT JOIN pur_prices pp
ON p.id=pp.product_id
AND pp.RN = 1 --Only show the most recent price less than current time
LEFT JOIN retail_prices rp
ON p.id=rp.product_id
AND RP.RN = 1 --Only show the most recent price less than current time
ORDER BY p.id;
最终结果应该是所有产品,无论他们是零售价还是购买价;但如果他们确实显示了之前最近时刻的零售/购买价格。我唯一担心的是这意味着所有定价都有一个开始的时刻(不允许空值!)
答案 2 :(得分:0)
您可能希望按照降序排列。
更改
ORDER BY products.id;
至
ORDER BY product.id ASC, moment DESC;