У меня есть 4 таблицы (назначенные, класс, выборные, статусные), которые я хочу перевести в одну таблицу (члены). Значения из 4 таблиц зависят от времени на основе таблицы истории (members_history). Желаемый результат состоит в том, что запрос должен выводить всех членов и текущую назначенную позицию или текущую выбранную позицию, класс и статус в строке членов и включать дополнительную информацию, полученную из внешних строк.
Так что вместо того, чтобы просто возвращаться:
id, имя пользователя, пароль, соль, name_first, name_last, date_join & date_leave;
Запрос вернет
id, имя пользователя, пароль, соль, name_prefix
, name_first, name_last, hours_extra
, date_join, date_leave, appointed
, class
, elected
& status
;
Там, где добавленный столбец не имеет текущего значения в истории, его результат должен быть НЕДЕЙСТВИТЕЛЕН.
Теперь я думаю, что могу сделать это с помощью подзапросов, но до сих пор бился головой о клавиатуру. Позже я сделаю еще один удар, но до тех пор, кто-нибудь еще, кто захочет сделать это, или попытается указать мне правильное направление?
Структура моих таблиц SQL (без каламбура) выглядит следующим образом:
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 - это FK для идентификатора в таблице участников, не каждый участник будет иметь историю на них (но в конечном итоге они все будут, поскольку каждый участник должен будет иметь класс и статус). members_history.value
- это ФК для 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);