【发布时间】:2015-11-21 03:54:15
【问题描述】:
我有 4 张桌子。一份用于公司,一份用于产品,一份用于公司地址,一份用于公司董事。
products、director 和 address 表与 company 表是一对多的关系。
所以一家公司可以有很多产品、很多地址和很多董事。
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)来为匹配董事(姓和 dob)和地址(邮政编码)的公司查找产品。
我只想每行列出一个匹配的产品,而不是单独列出每个董事或邮政编码。
到目前为止,我有以下查询,这似乎有效,但它很丑陋,我怀疑在速度和效率方面这是一种荒谬的方法。
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
-
我会重新考虑你的底层数据结构......我不明白
surname、dob和postcode都可以如何使用。如果您有surname和dob,那么您可以通过directors 表获得@987654329@...为什么您需要postcode中的addresses表中的company_id?这没有意义。 -
谢谢@upful。并非所有公司都一定有地址记录,也不是所有公司都一定有董事。它们是两件独立的东西,必须在公司表上加上墨水,所以我能看到的唯一方法是通过 company_id
-
在这种情况下,您可能会使用
OR运算符而不是AND... 所以WHERE (surname = :surname AND dob = :dob) OR postcode = :pesticide... 我认为确定哪家公司拥有这些产品很重要匹配您的搜索,而不仅仅是返回产品列表。