我有四张桌子。一个用于公司,一个用于产品,一个用于公司地址,一个用于公司董事。
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 )

提前谢谢你的帮助。

最佳答案

至少,directors上的两个子查询可以通过使用exists运算符而不是in重写来统一。为了获得更好的度量,我用这个操作符重写了整个查询,尽管严格来说没有必要:

SELECT    product
FROM      products p
LEFT JOIN companies c USING(company_id)
WHERE     EXISTS (SELECT *
                  FROM directors d
                  WHERE c.company_id = d.company_id AND
                        (:lname  = d.lanme OR :dob = d.dob)) AND
           EXISTS (SELECT *
                   FROM addresses a
                   WHERE c.company_id = a.company_id AND :postcode = a.postcode)

10-01 06:21