从所有产品的价格表中加入最新价格

问题描述 投票:0回答:3

我有一个产品和一个价格表(包含产品 ID、价格和时间戳列)。现在我需要加入简单选择的最新价格的产品。

简单连接将选择表中第一个保存的价格,但不是最新的。

    SELECT p.*, pp.price
    FROM products p
    INNER JOIN product_prices pp ON (pp.product_id = p.id)

所以我尝试加入选择最新的时间戳,但这只会返回所有记录的最新时间戳,而不是每个产品价格:

    SELECT p.*, pp.*
    FROM products p
    LEFT JOIN
        (SELECT product_id, ranking, MAX(timestamp) as timestamp
        FROM product_prices) pp 
        ON pp.product_id = p.id

是否有一种聪明/正确的方法来选择每个产品具有最新价格的所有产品?

mysql sql join select
3个回答
1
投票

你已经很接近了,但是你需要在子查询中使用

GROUP BY

SELECT p.*, pp.*
FROM products p LEFT JOIN
     (SELECT product_id, MAX(timestamp) as timestamp
      FROM product_prices
      GROUP BY product_id
     ) pp 
     ON pp.product_id = p.id;

不清楚

ranking
专栏是关于什么的。 它仅在您的查询中使用,在问题的其他地方未提及。

如果您想要整个

product_price
行,您可以使用额外的
JOIN
:

SELECT p.*, pp.*
FROM products p JOIN
     product_prices pp
     ON pp.product_id = p.id LEFT JOIN
     (SELECT product_id, MAX(timestamp) as timestamp
      FROM product_prices
      GROUP BY product_id
     ) ppm
     ON ppm.product_id = p.id AND ppm.timestamp = pp.timestamp;

0
投票

我认为你需要two加入这里。 第一个连接直接连接到

product_prices
表,以从该表中引入所需的列。 第二个连接是子查询,该子查询按产品聚合
product_prices
,以查找每个产品的最新条目。 然后,第二次连接会限制来自第一次连接的完整结果。

SELECT p.*, pp1.*
FROM products p
LEFT JOIN product_prices pp1
    ON p.id = pp1.product_id
INNER JOIN
(
    SELECT product_id, MAX(timestamp) AS max_ts
    FROM product_prices
    GROUP BY product_id
) pp2
    ON pp1.product_id = pp2.product_id AND
       pp1.timestamp = pp2.max_ts;

如果您使用 MySQL 8+,那么我们可以在这里利用窗口函数:

WITH cte AS (
    SELECT p.*, pp1.*,
        ROW_NUMBER() OVER (PARTITION BY p.id ORDER BY pp.timestamp DESC) rn
    FROM products p
    LEFT JOIN product_prices pp
        ON p.id = pp.product_id
)

SELECT *
FROM cte
WHERE rn = 1;

0
投票

请使用RANK功能获取产品的最新价格

例如:

SELECT 
    pp.product_id, pp.timestamp, pp.price, 
    RANK() OVER(PARTITION BY pp.product_id ORDER BY pp.timestamp DESC) Rnk
FROM product_prices pp
WHERE pp.Rnk = 1

您还可以加入您的产品表:

SELECT 
    p.id, p.description, pp.timestamp, pp.price, 
    RANK() OVER(PARTITION BY pp.product_id ORDER BY pp.timestamp DESC) Rnk
FROM products p
JOIN product_prices pp ON pp.product_id = p.id
WHERE pp.Rnk = 1
© www.soinside.com 2019 - 2024. All rights reserved.