查询三个表

时间:2014-12-11 20:57:08

标签: jquery sql database postgresql

我有以下架构:

|partner|
---------
 id

|contract|
----------
 id    
 partner_id
 termination_date

|comtract_items|
---------------
 id
 contract_id 
 product_id

我想选择所有拥有有效合同(termination_date is NULL)和的合作伙伴 没有与product_id 392和393签订合同。

到目前为止,这是我的查询:

SELECT 
    c.id,
    c.subject
FROM 
    contract_contract c

WHERE
    c.termination_date is NULL or c.termination_date > '2014-12-11'
    and c.id NOT IN (SELECT contract_id
                     FROM contract_item
                     WHERE product_id IN (392, 393))

如何构建查询的任何想法?

3 个答案:

答案 0 :(得分:1)

我认为你很亲密,但忘记了一些括号:

WHERE (c.termination_date is NULL or c.termination_date > '2014-12-11') and ...

以下是我将如何做到这一点::

SELECT DISTINCT c.partner_id
FROM Contract c
WHERE (c.TerminationDate IS NOT NULL OR c.TerminationDate > CURRENT_DATE)
AND NOT EXISTS (SELECT 1 FROM ContractItem
                WHERE contract_id = c.id
                AND product_id IN (392, 393))

答案 1 :(得分:1)

  

我想选择所有拥有有效合同的合作伙伴(te​​rmination_date为NULL),并且没有产品ID为392和393的合约。

这个SQL语句应该实现

SELECT c.partner_id
FROM contract c
INNER JOIN contract_items ci on ci.contract_id = c.id
WHERE (c.termination_date is NULL
    or c.termination_date > '2014-12-11') 
AND ci.productID NOT IN (392, 393);

答案 2 :(得分:1)

现在很清楚,"and with no contracts with the product_id's 392 and 393"应该排除与 任何 合同的合作伙伴与任何列入黑名单的合作伙伴product_id S:

SELECT *  -- unclear which columns you want
FROM   partner p
WHERE  EXISTS (
   SELECT 1
   FROM   contract_contract c
   WHERE (c.termination_date IS NULL OR c.termination_date > '2014-12-11')
   AND    c.partner_id = p.id
   )
AND    NOT EXISTS (
   SELECT 1
   FROM   contract_contract c
   JOIN   contract_item ci ON ci.contract_id = c.id
   WHERE  c.partner_id = p.id
   AND    ci.product_id IN (392, 393)
   );

在原始查询中,您可能需要括号才能在OR之前进行AND绑定。使用标准 operator precedence AND首先绑定 - 可能不是您想要的那样。

但是,在更新后的查询中,必要性已经消失,因为附加谓词已移至单独的EXISTS表达式。