Соединение отношения «один ко многим» для исключения некоторых строк на основе условия

#sql #join

#sql #Присоединиться

Вопрос:

У меня есть отношение «один ко многим» между customer Customer Contract таблицей и

Таблица клиентов

 id|name
 1|Jared  
 2|Taylor
 

Таблица контрактов с клиентами

 id|CustomerID|StatusID
 1|1         |2
 2|2         |1
 3|1         |2
 4|1         |3
 

Теперь я хочу создать представление для получения только клиента, у которого нет
последнего статуса 2 в customer contract

Ожидаемый результат

 id|CustomerID
 1|2        
 

Извлекается CustomerID 2, поскольку его последний статус не равен 2

Ответ №1:

Используйте not exists :

 select c.*
from customers c
where not exists (select 1
                  from customercontracts cc
                  where cc.customerid = c.id and cc.statusid = 2
                 );
 

Комментарии:

1. Разве я не могу добиться того же с помощью join?

2. @r_via . , , Да, но это почти прямой перевод того, что вы просите, в SQL.

3. Я обновил свой вопрос. Кроме того, разве join не лучше по производительности?

4. @r_via. . . Нет.

Ответ №2:

Я хочу создать представление для получения только клиента, у которого нет последнего статуса 2 в контракте с клиентом

Вы можете использовать коррелированный подзапрос для получения последнего статуса и использовать его для фильтрации:

 create view customer_view as
select c.*
from customer c
where (
    select statusid 
    from customercontracts cc 
    where cc.customerid = c.customerid 
    order by id desc 
    limit 1
) <> 2
 

Комментарии:

1. Является ли коррелированный подзапрос хорошим по производительности? У меня очень большой стол, и я хотел бы использовать наилучший подход

2. Для повышения производительности требуется индекс customercontract(customerid, id, statusid) .

3. У меня это уже есть, сейчас я провожу исследование по этому вопросу и обнаружил, что использование left outer join повышает производительность

4. @r_via: в целом это неверно. При наличии правильного индекса коррелированный подзапрос часто оказывается более эффективным.