I'm looking for a way to output a selected related record for each record in a table in MySQL. I'll explain further...
I have 2 tables currencies and exchange_rates. The tables are joined by a currency_code field and each currency record has multiple related exchange rate records, each exchange rate record represents a different day. So there is a 1:many relationship between currencies and exchange_rates.
I want to retrieve a full record from the exchange_rates table for each currency but with the ability to define specific criteria as to which related record to select. Not just the most recent exchange_rate for each currency but maybe the most recent exchange_rates record for each currency that has the field criteria_x=NULL.
It's a shame that you can't use LIMIT within a derived table otherwise something like this would be a neat and readable solution...
SELECT `currencies`.`currency_code`, `currencies`.`country`, `exchange_rates`.`id`, FROM_UNIXTIME(`exchange_rates`.`datestamp`), `rate` FROM `currencies` INNER JOIN ( SELECT `id`, `currency_code`, `invoice_id`, `datestamp`, `rate` FROM `exchange_rates` WHERE `criteria_x`=NULL AND `criteria_y` LIKE 'A' ORDER BY `datestamp` DESC LIMIT 0, 1 ) AS `exchange_rates` ON `currencies`.`currency_code`=`exchange_rates`.`currency_code` ORDER BY `currencies`.`country` The LIMIT clause is applied to the parent query not the derived table.
This is the only way I've found to do this...
SELECT `currencies`.`currency_code`, `currencies`.`country`, FROM_UNIXTIME( SUBSTRING_INDEX( SUBSTRING_INDEX(`exchange_rates`.`concat`, '-', 1), '-', -1)) AS `datestamp`, SUBSTRING_INDEX( SUBSTRING_INDEX(`exchange_rates`.`concat`, '-', 2), '-', -1) AS `id`, SUBSTRING_INDEX( SUBSTRING_INDEX(`exchange_rates`.`concat`, '-', 3), '-', -1) AS `rate` FROM `currencies` INNER JOIN ( SELECT `currency_code`, MAX(CONCAT_WS('-', `datestamp`, `id`, `rate`)) AS `concat` FROM `exchange_rates` WHERE `criteria_x`=NULL AND `criteria_y` LIKE 'A' GROUP BY `exchange_rates`.`currency_code` ) AS `exchange_rates` ON `currencies`.`currency_code`=`exchange_rates`.`currency_code` ORDER BY `currencies`.`country` So concatenating a bunch of fields together and running a MAX() on it to get my sort order within the group, then parsing those fields out in the parent query with SUBSTRING_INDEX(). The problem is that this method only works when I can use a MIN() or MAX() on the concatenated field. It wouldn't be ideal if I wanted to sort a string or sort by multiple criteria but limit to a single record.
Also it causes me physical pain to have to resort to horrible string manipulation to get the data I want from a relational database — there has to be a better way!
Anyone got any suggestions of a better method?