Настройка: база данных контактов с использованием 4 таблиц
- Контакты
- Город
- States
- Молнии
Состав:
CREATE TABLE `contacts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`last` varchar(100) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`first` varchar(100) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`prefix` varchar(50) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`suffix` varchar(50) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`address` varchar(100) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`address_1` varchar(100) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`city_id` int(100) DEFAULT NULL,
`state_id` int(20) DEFAULT NULL,
`alt_address_1` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`alt_address_2` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`alt_city` varchar(100) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`alt_state` varchar(20) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`alt_zip` varchar(15) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`publish_name` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`salutation` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`mail_label` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`solicitor` varchar(100) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`is_volunteer` tinyint(1) DEFAULT NULL,
`is_sponsor` tinyint(1) DEFAULT '0',
`is_company` tinyint(1) DEFAULT '0',
`is_foundation` tinyint(1) DEFAULT '0',
`status` varchar(15) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`created_on` datetime NOT NULL,
`created_by` varchar(30) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`modified_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`modified_by` varchar(100) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`agency_id` int(25) DEFAULT NULL,
`primary_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `primary_id` (`primary_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3008 DEFAULT CHARSET=utf8
CREATE TABLE `cities` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`city` varchar(50) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`stateid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `city` (`city`)
) ENGINE=InnoDB AUTO_INCREMENT=128 DEFAULT CHARSET=utf8
CREATE TABLE `states` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`abbreviation` varchar(2) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`state` varchar(20) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `state` (`state`),
UNIQUE KEY `abbreviation` (`abbreviation`),
KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=52 DEFAULT CHARSET=utf8
CREATE TABLE `zips` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`zip` varchar(10) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`cityid` int(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `zip` (`zip`)
) ENGINE=InnoDB AUTO_INCREMENT=128 DEFAULT CHARSET=utf8
Я заполнил контакты 111 контактами, состояния - это просто все штаты, и города имеют соответствующие идентификационные ключи, которые относятся к идентификатору штата, почтовые индексы имеют ключ, соответствующий городу.
Запрос состоит в том, чтобы создать список людей, которые соответствуют соответствующим полям. Вот запрос.
SELECT concat(contacts.last,' ', contacts.first) as name
, cities.city
, zips.zip
FROM contacts
JOIN cities
ON cities.id = contacts.city_id
JOIN states ON states.id = contacts.state_id
JOIN zips ON zips.cityid = cities.id
Этот запрос возвращает 338 строк из 11 возможных контактов. Там очевидные дубликаты. Это происходит, когда я присоединяюсь к почтовым индексам, которые, поскольку они принадлежат более чем одному городу, сопоставляются для каждого города (я думаю, это то, что происходит). У кого-нибудь есть ответ, как правильно объединить эти таблицы?
Спасибо.
Рич