从多个表加入,不在MySQL中返回所需的数据

时间:2012-12-07 18:44:52

标签: mysql jointable

我的数据库中有三个表(contractspartnerscustomers),合同可以用于客户和合作伙伴。

我只将合同数据保存在contracts表和customers表中,partners表包含一个名为contract_id的字段,该字段是contracts的外键id字段。

不,我想选择合约并在列表中显示它们,但如果合同同时用于客户和合作伙伴,我希望我的列表能够同时显示它们,但我无法使其合作。

我的查询是:

SELECT c.*, p.id AS partner_id, p.name AS partner_name, 
       cu.id AS customer_id, cu.name AS customer_name
FROM contracts AS c 
LEFT JOIN partners AS p ON c.id = p.contract_id
LEFT JOIN customers AS cu ON c.id = cu.contract_id

样品: contract表的记录如下:

    id  |   title   |   contract_start  |   contract_end
-------------------------------------------------------------
    1   |   Test    |   2012-10-02      |   2013-10-02
    2   |   Test2   |   2012-09-27      |   2013-09-27

customers表的记录如下:

    id  |   code    |   name                |   contract_id
-------------------------------------------------------------
    1   |   123456  |   Customer1           |   1
    2   |   654321  |   Dummy Co. LTD.      |   2

partners表的记录如下:

    id  |   code    |   name                |   contract_id
-------------------------------------------------------------
    1   |   789456  |   Partner1            |   1

不,我想要一个包含3条记录的列表,每条记录显示一份合同(考虑其中一条重复),每条记录显示合作伙伴或客户名称和ID。如果合同涉及客户,合作伙伴字段应为null,反之亦然。

1 个答案:

答案 0 :(得分:4)

你说:

  

不,我想选择合约并将其显示在列表中,但如果合同同时用于客户和合作伙伴,我希望我的列表显示两者

您可能需要单独加入两个表并使用UNION

SELECT c.*, 
       p.id AS partner_id, p.name AS partner_name, 
       NULL AS customer_id, NULL AS customer_name
FROM contracts AS c 
INNER JOIN partners AS p ON c.id = p.contract_id

UNION ALL

SELECT c.*, 
       NULL AS partner_id, NULL AS partner_name, 
       cu.id AS customer_id, cu.name AS customer_name
FROM contracts AS c 
INNER JOIN customers AS cu ON c.id = cu.contract_id

UNION ALL

SELECT c.*, 
       NULL, NULL,
       NULL, NULL 
FROM contracts AS c 
WHERE NOT EXISTS ( SELECT *  
                   FROM partners AS p
                   WHERE c.id = p.contract_id
                 )
  AND NOT EXISTS ( SELECT *
                   FROM customers AS cu 
                   WHERE c.id = cu.contract_id 
                 ) ;

(不同输出设置的另一种方式)
如果您愿意,可以将最后四列合并为两列,添加一列以区分合作伙伴和客户:

SELECT c.*, 
       p.id AS partner_customer_id, p.name AS partner_customer_name, 'P' AS type 
FROM contracts AS c 
INNER JOIN partners AS p ON c.id = p.contract_id

UNION ALL

SELECT c.*, 
       cu.id , cu.name, 'C'
FROM contracts AS c 
INNER JOIN customers AS cu ON c.id = cu.contract_id ;