Присоединяйтесь к новейшей цене из прайс-листа на все товары - PullRequest
0 голосов
/ 15 июня 2019

У меня есть продукт и таблица цен (со столбцами 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

Существует ли разумный / правильный способ выбора всех продуктов с самой новой ценой на продукт?

Ответы [ 2 ]

0 голосов
/ 15 июня 2019

Я думаю, вам нужно два присоединения здесь.Первое соединение осуществляется непосредственно к таблице 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 голосов
/ 15 июня 2019

Вы близки, но вам нужно 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...