PostgreSQL使用来自多个联接的数据来查询来自另一个表的数据

时间:2017-10-31 22:55:29

标签: sql postgresql

我想要用于1个SQL查询的3个表。

customers:
 - id
 - first_name
 - last_name

customer_professional:
 - id
 - customer_id
 - professional_id

company_customer:
 - id
 - customer_id
 - company_id

我正在尝试运行的查询是抓住professional_id = ?company_id = ?所有客户。这是我到目前为止提出的查询。

SELECT * 
FROM   customers c 
       INNER JOIN customer_professional cp 
               ON c.id = cp.customer_id 
       INNER JOIN company_customer cc 
               ON c.id = cc.customer_id 
WHERE  ( cp.professional_id = '36ec09ec-6b07-45e3-ae2d-a77bfe381bab' ) 
        OR ( cc.company_id = '36ec09ec-6b07-45e3-ae2d-a77bfe381baa' ) 
ORDER  BY "first_name" 
LIMIT  50; 

此查询仅返回customer_professionalcompany_customer中的客户。我正在尝试运行的查询应该返回所有客户,即使它们只在1个联结表中。

SIDE NOTE

我知道你在想什么,这应该只有2张桌子。我同意你的看法。

更新

我期待的数据:

customers table:
|  id  |  first_name  |  last_name  |
-------------------------------------
|  1   |  peter       |  griffin    |
|  2   |  meg         |  griffin    |
|  3   |  stewie      |  griffin    |
|  4   |  louis       |  griffin    |
|  5   |  bryan       |  griffin    |

customer_professional table:
|  id  |  customer_id  |  professional_id  |
--------------------------------------------
|  1   |  1            |  1                |
|  2   |  2            |  1                |
|  3   |  5            |  1                |

company_customer table:
|  id  |  customer_id  |  company_id  |
---------------------------------------
|  1   |  3            |  2           |
|  2   |  4            |  2           |
|  3   |  5            |  2           |

因此,对于我想要运行的查询,我有company_idprofessional_id,我希望返回属于专业人士或公司的客户。

查询:

SELECT * 
FROM   customers c 
       INNER JOIN customer_professional cp 
               ON c.id = cp.customer_id 
       INNER JOIN company_customer cc 
               ON c.id = cc.customer_id 
WHERE  ( cp.professional_id = '1 ) 
        OR ( cc.company_id = 2 ) 
ORDER  BY "first_name" 
LIMIT  50; 

这只会返回:

|  id  |  first_name  |  last_name  |
-------------------------------------
|  5   |  bryan       |  griffin    |

我正在尝试运行的查询应该返回

|  id  |  first_name  |  last_name  |
-------------------------------------
|  1   |  peter       |  griffin    |
|  2   |  meg         |  griffin    |
|  3   |  stewie      |  griffin    |
|  4   |  louis       |  griffin    |
|  5   |  bryan       |  griffin    |

3 个答案:

答案 0 :(得分:1)

这是inner join的作用:它只保留表之间的交集。这只是两者中出现的条目。我认为你所追求的是left join,它保留了所有允许你使用where子句过滤它们的条目。

答案 1 :(得分:0)

您需要left join而不是inner join

答案 2 :(得分:0)

据推测,你想要这样的东西:

SELECT c.* 
FROM customers c INNER JOIN
     customer_professional cp 
     ON c.id = cp.customer_id AND
        cp.professional_id = '36ec09ec-6b07-45e3-ae2d-a77bfe381bab' INNER JOIN
     company_customer cc 
     ON c.id = cc.customer_id AND
        cc.company_id = '36ec09ec-6b07-45e3-ae2d-a77bfe381baa' 
WHERE cp.customer_id IS NOT NULL OR cc.customer_id IS NOT NULL
ORDER  BY "first_name" 
LIMIT  50; 

首先,我发现你的问题令人困惑。文字说“和”,但你似乎想要“或”。其次,另外两个表是 junction 表,而不是 pivot 表。

变化是:

  • 这仅选择customers表中的列。我不确定你真的需要其他专栏。
  • 有关ID的条件已移至ON条款。
  • 联接更改为LEFT JOIN s。
  • WHERE子句检查至少有一个匹配。