我有4個表格。一個用於公司,一個用於公司地址的產品,另一個用於公司董事。在MySql中選擇與一對多對應關係匹配的行
產品,董事和地址表與公司表格有着一對多的關係。
因此,一家公司可以有許多產品,許多地址和許多董事。
CREATE TABLE IF NOT EXISTS `companies` (
`company_id` int(11) NOT NULL AUTO_INCREMENT,
`company_name` varchar(50) NOT NULL,
PRIMARY KEY (`company_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
CREATE TABLE IF NOT EXISTS `products` (
`product_id` int(11) NOT NULL AUTO_INCREMENT,
`company_id` int(11) NOT NULL,
`product` varchar(50) NOT NULL,
PRIMARY KEY (`product_id`),
KEY `company_id` (`company_id`),
KEY `product` (`product`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
CREATE TABLE IF NOT EXISTS `directors` (
`director_id` int(11) NOT NULL AUTO_INCREMENT,
`company_id` int(11) NOT NULL,
`surname` varchar(100) NOT NULL,
`dob` date NOT NULL,
PRIMARY KEY (`director_id`),
KEY `company_id` (`company_id`),
KEY `surname` (`surname`),
KEY `dob` (`dob`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
CREATE TABLE IF NOT EXISTS `addresses` (
`address_id` int(11) NOT NULL AUTO_INCREMENT,
`company_id` int(1) NOT NULL,
`postcode` varchar(10) NOT NULL,
PRIMARY KEY (`address_id`),
KEY `company_id` (`company_id`),
KEY `postcode` (`postcode`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;
INSERT INTO `companies` (`company_id`, `company_name`) VALUES
(1, 'Honda'),
(2, 'Toyota');
INSERT INTO `products` (`product_id`, `company_id`, `product`) VALUES
(1, 1, 'Civic'),
(2, 1, 'Accord'),
(3, 2, 'Corolla'),
(4, 2, 'Prius'),
(5, 1, 'CRV');
INSERT INTO `directors` (`director_id`, `company_id`, `surname`, `dob`) VALUES
(1, 1, 'Jones', '1990-09-09'),
(2, 1, 'Smith', '1980-08-08'),
(3, 2, 'Lucas', '1970-07-07'),
(4, 1, 'Kelly', '1960-06-06'),
(5, 2, 'Monty', '1950-05-05');
INSERT INTO `addresses` (`address_id`, `company_id`, `postcode`) VALUES
(6, 1, '12345'),
(7, 2, '23456'),
(8, 1, '34567'),
(9, 2, '45678'),
(10, 1, '56789');
我試着寫一個高效的查詢(使用MySQL/PDO)找到產品匹配匹配董事(姓氏和出生日期)及地址(郵編),公司。
我只想列出每行一個匹配的產品,而不是單獨列出每個導演或郵編。
到目前爲止,我有下面的查詢,這似乎工作,但它是醜陋的,我懷疑在速度和效率方面做出這種荒謬的方式。
SELECT product
FROM products p
LEFT JOIN companies c USING(company_id)
WHERE :lname IN (
SELECT surname
FROM directors d
WHERE c.company_id = d.company_id)
AND :dob IN (
SELECT dob
FROM directors d
WHERE c.company_id = d.company_id)
AND :postcode IN (
SELECT postcode
FROM addresses a
WHERE c.company_id = a.company_id)
預先感謝您的幫助。
你想工作'更好'的工作代碼是最好張貼在[codereview](http://codereview.stackexchange.com/) –
我會重新考慮你的基礎數據結構...我不明白'姓氏' ','dob'和'postcode'都可以使用。如果你有'surname'和'dob',那麼你通過director表有'company_id' ...爲什麼你需要'postcode'中'addresses'表中的'company_id'?這沒有意義。 – upful
謝謝@upful。並非所有公司都必須有地址記錄,並非所有公司都必須有董事。他們是兩個獨立的東西,必須簽署公司表,所以我能看到做到這一點的唯一方法是通過company_id – ratherBeKiting