I have 4 tables (appointed, class, elected, status) that I want to cross reference into a single table's (members) column. The values of the of 4 tables are time sensitive based off a history table (members_history). The desired result is that the query should output all members and the current appointed position or current elected position, class, and status within the members row and include additional information obtained from the foreign rows.
So instead of just returning:
id, username, password, salt, name_first, name_last, date_join & date_leave;
The query would return
id, username, password, salt, name_prefix
, name_first, name_last, hours_extra
, date_join, date_leave, appointed
, class
, elected
& status
;
Wherever an added column does not have a current value in history it's result should be NULL.
Now I think I can do this with sub-querys, but have been so far banging my head against the keyboard. I'll take another swing at it later, but until then, anyone else willing to give it a shot, or attempt to point me in the right direction?
The structure of my SQL (no pun intended) tables is as follows:
CREATE TABLE IF NOT EXISTS `members` ( `id` mediumint(3) unsigned NOT NULL auto_increment COMMENT 'Members Unique Id', `username` varchar(32) collate utf8_bin NOT NULL COMMENT 'Mebers Username', `password` varchar(64) collate utf8_bin NOT NULL COMMENT 'Members Password Hash', `salt` varchar(32) collate utf8_bin NOT NULL COMMENT 'Members Password Salt', `name_first` varchar(32) collate utf8_bin NOT NULL COMMENT 'Members First Name', `name_last` varchar(32) collate utf8_bin NOT NULL COMMENT 'Members Last Name', `date_join` date NOT NULL COMMENT 'Members Join Date', `date_leave` date default NULL COMMENT 'Members Resgination Date (If Applicable)', PRIMARY KEY (`id`), ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Members id in this table = mid in other tables'; CREATE TABLE IF NOT EXISTS `members:apointed` ( `id` tinyint(3) unsigned NOT NULL auto_increment COMMENT 'Unique value', `name_prefix` varchar(8) collate utf8_bin NOT NULL COMMENT 'Prefix Added to Members Name', `hours_extra` decimal(4,2) NOT NULL COMMENT 'Hours Given as Bonus for Holding this Position.', `position` varchar(40) collate utf8_bin NOT NULL COMMENT 'Name of the Posisiton', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Undefined within the SOP or By-Laws.'; CREATE TABLE IF NOT EXISTS `members:class` ( `id` tinyint(3) unsigned NOT NULL auto_increment COMMENT 'Unique Id', `class` varchar(8) collate utf8_bin NOT NULL COMMENT 'Unique Value', PRIMARY KEY (`id`), UNIQUE KEY `value` (`class`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Article I, Section 1 Subsection B: Classes of Membership'; CREATE TABLE IF NOT EXISTS `members:elected` ( `id` tinyint(3) unsigned NOT NULL auto_increment COMMENT 'Unique value', `name_prefix` varchar(8) collate utf8_bin NOT NULL COMMENT 'Prefix Added to Members Name', `hours_extra` decimal(4,2) NOT NULL COMMENT 'Hours Given as Bonus for Holding this Position.', `position` varchar(40) collate utf8_bin NOT NULL COMMENT 'Name of the Posisiton', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Article II'; CREATE TABLE IF NOT EXISTS `members:status` ( `id` tinyint(3) unsigned NOT NULL auto_increment COMMENT 'Bit''s Place', `status` varchar(16) collate utf8_bin NOT NULL COMMENT 'Categorie''s Name', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Article I, Section 1, Subsection A: Categories of Membership'; CREATE TABLE IF NOT EXISTS `members_history` ( `id` int(10) unsigned NOT NULL auto_increment COMMENT 'Unique Id', `mid` tinyint(3) unsigned NOT NULL COMMENT 'Members Unique Id.', `table` enum('class','elected','appointed','status') NOT NULL COMMENT 'Name of Table that was Edited.', `value` tinyint(3) unsigned NOT NULL COMMENT 'Value', `start` date NOT NULL COMMENT 'Value''s Effect Date', `end` date default NULL COMMENT 'Value''s Expiration Date', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Member History';
members_history.mid is a FK for id in the members table, not every member will have history on them (but eventually they all will, as every member will have to have a class and status). members_history.value
is a FK for members:{members_history.table}.id
;
INSERT INTO `members` (`id`, `username`, `password`, `salt`, `name_first`, `name_last`, `date_join`, `date_join`) VALUES ( 1, 'Dygear',MD5('pass'), 's417', 'Mark', 'Tomlin', DATE(), NULL), ( 2, 'uberusr',MD5('p455'), '235f', 'Howard', 'Singer', DATE(), NULL), ( 3,'kingchief',MD5('leet'), '32fs','Christopher', 'Buckham', DATE(), NULL); INSERT INTO `members:apointed` (`id`, `name_prefix`, `hours_extra`, `posisiton`) VALUES ( 1, '', 0.00, 'Crew Chief'), ( 2, '', 20.00, 'Engineer'), ( 3, 'Lt.', 40.00, 'Lieutenant'), ( 4, 'Capt.', 60.00, 'Captin'), ( 5, 'Chief.', 80.00, '3rd Assistant Chief of Operation'); INSERT INTO `members:class` (`id`, `class`) VALUES ( 1, 'Class I'), ( 2, 'Class II'); INSERT INTO `members:elected` (`id`, `name_prefix`, `hours_extra`, `posisiton`) VALUES ( 1, '', 40.00, 'Trustee'), ( 2, '', 40.00, 'Chairman of the Board'), ( 3, 'Prez.', 40.00, 'President'), ( 4, 'VPrez.', 40.00, 'Vice-President'), ( 5, '', 40.00, 'Recording Secretary'), ( 6, '', 40.00, 'Service Secretary'), ( 7, '', 40.00, 'Corresponding Secretary'), ( 8, '', 40.00, 'Financial Secretary Treasuer'), ( 9, '', 40.00, 'Assistant Financial Secretary Treasuer'), ( 10, 'Chief.', 80.00, 'Chief of Operations'), ( 11, 'Chief.', 80.00, 'First Deputy Chief of Operations'), ( 12, 'Chief.', 80.00, 'Second Deputy Chief of Operation'); INSERT INTO `members:status` (`id`, `status`) VALUES ( 1, 'Active'), ( 2, 'Inactive'), ( 3, 'Student'), ( 4, 'Probationary'), ( 5, 'Lifetime'), ( 6, 'Cadet'), ( 7, 'Honorary'), ( 8, 'Medical'), ( 9, 'Military'), ( 10, 'Resigned'), ( 11, 'Disvowed'); INSERT INTO `members_history` (`id`, `mid`, `table`, `value`, `start`, `end`) VALUES (NULL, 1, 'apointed', 3, DATE(), NULL), (NULL, 1, 'class', 1, DATE(), NULL), (NULL, 1, 'status', 1, DATE(), NULL), (NULL, 2, 'elected', 4, DATE(), NULL), (NULL, 2, 'class', 1, DATE(), NULL), (NULL, 2, 'status', 1, DATE(), NULL), (NULL, 3, 'apointed', 10, DATE(), '2010-05-01'), (NULL, 3, 'class', 1, DATE(), NULL), (NULL, 3, 'status', 1, DATE(), NULL);