2014-12-11 4 views
0

У меня есть следующая схема:запросы за три таблицы

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

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

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

Я хочу, чтобы выбрать все партнер, которые имеют действующий контракт (termination_date is NULL) и без каких-либо контрактов с product_id «s 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)) 

Любые идеи, как построить запрос?

+0

Ваш запрос выглядит разумным. В чем проблема? –

+0

У вас есть 'contract_contract.subject' в вашем запросе, но не в вашем макете таблицы. Просьба уточнить. Кроме того, ограничение «без контрактов с 392 и 393» product_id должно исключать партнера только того контракта, к которому он применим. –

+0

его следующее отношение> у одного партнера может быть много контрактов, а один контракт может иметь много строк. с моим запросом я хочу получить всех партнеров, которые havnt один из этих продуктов в любом контракте – ghovat

ответ

1

Это теперь ясно, что "and with no contracts with the product_id's 392 and 393" предполагается исключить партнер, которые имеют любого контракта с любым из этих черного списка product_id с:

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 precedenceAND связывается первым - возможно, не то, что вы хотите там.

Однако в обновленном запросе необходимость исчезла, поскольку дополнительный предикат переместился в отдельное выражение EXISTS.

+0

его следующее отношение> у одного партнера может быть много контрактов, а один контракт может иметь много строк. с моим запросом я хочу получить весь партнер, который havnt один из этих продуктов в любом контракте – ghovat

+0

@GeorgSattler: Адаптировал запрос соответствующим образом. –

+0

удивительный, спасибо! – ghovat

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)) 
+0

его следующее отношение> один партнер может иметь много контрактов и один контракт может иметь много строк. с моим запросом я хочу получить весь партнер, который havnt один из этих продуктов в любом контракте – ghovat

1

Я хочу, чтобы выбрать все партнера, которые имеют действительный контракт (term_date имеет значение NULL) и который не заключает контрактов с идентификаторами продукта 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); 
Смежные вопросы