Question

I'm a little rushed for time so I know I could look for the answer myself but stackoverflow is faster! :)

I have a table with data let's pretend it is product information. the table keeps track of when the product data is updated. If I run a query like

SELECT * FROM productChangeLog where change = 'price changed'

I get results like

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'

what I want to do is select only the most recent 'price change' for each product. what do I need to add to my query so that i would only get row 241 and 512? the higher id is always the more recent change

thanks so much!

Was it helpful?

Solution

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

OTHER TIPS

GROUP BY the key-fields and use HAVING clause to extract the record.

In your case, you may try,

-- 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

OR

-- 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

These are illegal queries in standard SQL, but should work in MySQL.

BTW, how is your result showing row 242 and 517 with 'description changed'?

This approach accomplishes the same thing, but uses ANSI syntax and can be extended to incorporate multiple fields:

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

If { Group, Date } is not unique, you need just a little more code:

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))
    )
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top