Часто мне приходится выбирать клиентов, которые выполнили {набор критериев A} транзакций, а не ДРУГОЙ тип транзакций.Пример данных:
create table customer (name nvarchar(max))
insert customer values
('George'),
('Jack'),
('Leopold'),
('Averel')
create table trn (id int,customer nvarchar(max),product char(1))
insert trn values
(1,'George','A'),
(2,'George','B'),
(3,'Jack','B'),
(4,'Leopold','A')
Допустим, мы хотим найти всех покупателей, которые купили продукт «А», а не что-либо еще (в данном случае, B).Наиболее типичный способ сделать это включает в себя соединение таблицы транзакций с самим собой:
select * from customer c
where exists(select 1 from trn p where p.customer=c.name and product='A')
and not exists(select 1 from trn n where n.customer=c.name and product='B')
Мне было интересно, есть ли лучший способ сделать это.Имейте в виду, что таблица транзакций обычно должна быть огромной.
Как насчет этой альтернативы:
select * from customer c
where exists
(
select 1
from trn p
where p.customer=c.name
group by p.customer
having max(case when product='B' then 2 when product='A' then 1 else 0 end)=1
)
Будет ли тот факт, что таблица транзакций используется только один раз, компенсировать необходимые вычисления агрегации?