#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: в целом это неверно. При наличии правильного индекса коррелированный подзапрос часто оказывается более эффективным.