sql - 使用 JOIN 和限制构建 SQL 查询

标签 sql postgresql join left-join

请帮助我构建 PostgreSQL 查询。 有 2 个表:products(id, title) 和 prices(id, product_id, price_type, moment, value)

moment - 时间戳,可以是过去也可以是 future

假设 price_type 只有两个选项:retailpurchase

但一个产品可能有多个不同时刻的零售价。

我需要选择所有具有实际零售价和采购价的产品,其中 moment 比现在少。

我能做到

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;

它有效,但返回 具有所有价格的产品,但我只需要最后的价格(按时刻)。

最佳答案

只需使用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

关于sql - 使用 JOIN 和限制构建 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45761088/

相关文章:

php - SQL - 如果存在 - 选择 A - 否则 - 选择 B

postgresql - 只允许 COUNT 到 Postgres 角色?

sql - 如何在 PostgreSQL 中的连接中使用 Case 语句?

php - 安全地实现 "configurable"加入系统

SQL Union 与 COUNT() 函数未返回预期结果

mysql - 将日期字段转换为仅返回日期字段

每个客户端上的 C# Sql-server

postgresql - 函数返回 "query has no destination for result data"

postgresql - Postgres 数据库中的触发器

MySQL 查询(或 Doctrine 1.2 查询)- 从连接表和过滤器中获取最新项目