Link to home
Start Free TrialLog in
Avatar of KurtVon

asked on

Filtering data for last date, getting all columns.

I'm storing grid data in a database, but "journaling" each cell to allow retrieving the grid state at a particular time.  The initial storage uses the columns name, date, row, col, value.

To change a cell value I just insert a row with the row, col, and value set and date set to NOW().  To delete, value is set to NULL.

But to get the current cell data is proving too difficult.  I know I want to do something like:

SELECT row, col, value FROM journal WHERE name = ? GROUP BY row, col HAVING date = MAX(date)

but of course this won't work since the value column is not part of the GROUP BY.

I could get a value based on the date, but need to use the row and col values as well, and each row and column may have a different MAX(date).

I can't be the first person to try journaling data in MySQL, so a solution to the query or a pointer to teh right way to do this would be accepted.

Thanks for any help.
Avatar of virmaior
Flag of United States of America image

Link to home
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of KurtVon


Cool, that does it!  Works on the MS Access dev machine too (well, if LIMIT is replaced with TOP).

And unless I'm misunderstanding how this works, I can use add

WHERE = ? AND j1.column IN ( ?, ?, ... )

to filter the results.

If I give the inner select a temporary name, I should still be able to do a WHERE clause on values too, right?
yes to all of the questions but the last.

to do it to the last one, you can either use WHERE on the inner query or you can HAVING on the entire query.
Avatar of KurtVon


A WHERE on the inner query will return an older value, and HAVING won't work without a GROUP BY.  I suspect I'm going to have to drop another select around it to do value filtering, but that's fine

For the record, right after I implemented this, the company SQL guy came up with

SELECT journal.row, journal.col, journal.value FROM journal INNER JOIN ( SELECT row, col, MAX(date) AS max_date FROM journal GROUP BY row, col ) AS T ON journal.row = T.row AND journal.col = T.col AND = T.max_date;

but at a glance it looks like his solution is much slower (certainly harder to read).