MySQL выбрать на основе двух критериев

Я немного тороплюсь, поэтому знаю, что могу сам найти ответ, но переполнение стека происходит быстрее!:)

У меня есть таблица с данными, давайте представим, что это информация о продукте. таблица отслеживает, когда данные продукта обновляются. Если я запускаю запрос как

SELECT * FROM productChangeLog where change = 'price changed'

Я получаю результаты как

id  product  date       change
---------------------------------------------    
236 product1 03/14/2011 'price changed'    
241 product2 03/14/2011 'price changed'    
242 product2 03/14/2011 'description changed'    
512 product1 05/16/2011 'price changed'    
517 product1 05/16/2011 'description changed'

я хочу выбрать только самое последнее "изменение цены" для каждого продукта. Что мне нужно добавить к моему запросу, чтобы я получил только строки 241 и 512? чем выше идентификатор, тем более свежие изменения

Спасибо большое!

3 ответа

Решение
SELECT t.max_id, t.product, pcl.date, pcl.change
    FROM (SELECT product, MAX(id) AS max_id
              FROM productChangeLog 
              WHERE change = 'price changed'
              GROUP BY product) t
        INNER JOIN productChangeLog pcl
            ON t.max_id = pcl.id

GROUP BY ключевые поля и использовать предложение HAVING для извлечения записи.

В вашем случае вы можете попробовать,

-- Don't use this if the product data can be updated twice on
-- the same day since the date field doesn't have a timestamp
SELECT * FROM productChangeLog where change = 'price changed' 
GROUP BY product HAVING MAX(date) = date

ИЛИ ЖЕ

-- Assuming the id is an integer field, this might be faster
SELECT * FROM productChangeLog where change = 'price changed' 
GROUP BY product HAVING MAX(id) = id

Это недопустимые запросы в стандартном SQL, но они должны работать в MySQL.

Кстати, как ваш результат показывает строки 242 и 517 с "измененным описанием"?

Этот подход выполняет то же самое, но использует синтаксис ANSI и может быть расширен для включения нескольких полей:

SELECT
  *
FROM
  Table AS T1
WHERE
  NOT EXISTS
    (
    SELECT * FROM Table AS T2 WHERE T1.Group = T2.Group AND T2.Date < T1.Date
    )

Если { Group, Date } не уникален, вам нужно немного больше кода:

SELECT
  *
FROM
  Table AS T1
WHERE
  NOT EXISTS
    (
    SELECT * FROM Table AS T2 WHERE T1.Group = T2.Group AND (T2.Date < T1.Date OR (T1.Date = T2.Date AND T2.ID < T1.ID))
    )
Другие вопросы по тегам