I want to get the latest MainNumber, Serial, BarType and Notes for a given MainNumber
, if they exist. Note that BarType is stored in a lookup table and referenced with BarID.
Unreason came up with this:
SELECT @MainNumber, COALESCE(n.Notes, 'None')
FROM numbers
LEFT JOIN notes n ON numbers.MainNumber = n.MainNumber
LEFT JOIN notes n2 ON n.MainNumber = n2.MainNumber AND n.Date < n2.Date
WHERE n2.Date IS NULL AND numbers.MainNumber = @MainNumber
This is fine whether Notes is NULL
or not, but now I need the Serial and the BarType. A MainNumber may have been assigned to multiple Serials during its lifetime, but I only want the latest Serial. (I'll need to do this with about 15 other fields in other tables, so a performant answer would be appreciated where possible)
Tables
Numbers Table:
CREATE TABLE `numbers` (
`ID` int(10) unsigned NOT NULL auto_increment,
`MainNumber` varchar(11) NOT NULL,
`Serial` varchar(20) NOT NULL,
`Date` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`ID`),
UNIQUE KEY `Serial` (`Serial`)
) ENGINE=MyISAM AUTO_INCREMENT=460 DEFAULT CHARSET=latin1
Notes table:
CREATE TABLE `notes` (
`ID` int(10) unsigned NOT NULL auto_increment,
`MainNumber` varchar(11) NOT NULL,
`Notes` longtext NOT NULL,
`Date` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`ID`),
KEY `MainNumber` (`MainNumber`)
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
ref_bars table:
CREATE TABLE `ref_bars` (
`BarID` varchar(6) NOT NULL,
`BarType` varchar(30) NOT NULL,
PRIMARY KEY USING BTREE (`BarID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
bars table:
CREATE TABLE `bars` (
`ID` int(10) unsigned NOT NULL auto_increment,
`MainNumber` varchar(11) NOT NULL,
`BarID` varchar(6) NOT NULL,
`Date` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`ID`),
KEY `MainNumber` (`MainNumber`)
) ENGINE=MyISAM AUTO_INCREMENT=212 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
Sample Data
SELECT * FROM notes
:
'ID','MainNumber','Notes','Date'
'1','1','repaired','2009-03-23 12:00:00'
'2','1','replaced','2009-08-15 19:20:05'
Note: two rows for MainNumber = 1, but no row for a MainNumber of 2. The IDs are just technical and are never used.
SELECT * FROM numbers
:
'ID','MainNumber','Serial','Date'
'1','1','4642785154854','2008-08-15 12:30:00'
'2','1','4642315642316','2009-08-15 12:50:00'
'3','2','5412558456223','2010-08-15 11:30:00'
SELECT * FROM bars
:
'ID','MainNumber','BarID','Date'
'1','1',1,'2008-08-15 12:30:00'
'2','1',2,'2009-08-15 12:50:00'
'3','2',2,'2010-08-15 11:30:00'
SELECT * FROM ref_bars
:
'BarID','BarType'
'1','Banned'
'2','Payment required'
Expected Output
MainNumber = 1
MainNumber,Notes,Banned,Unpaid
'1','replaced','Yes','Yes'
MainNumber = 2
MainNumber,Notes,Banned,Unpaid
'2','None','No','Yes'
Edit: Fixed it and tested it, whilst making things clearer (hopefully). I was rushed off to do other things earlier today, sorry for wasting people's time with a badly-written, incomplete question.
Updated to clarify the more complex requirements