Здравствуйте, ., Вы писали:
.>Как такой запрос сфарганить?
.>table Sale(id)
.>table SaleItem(saleId, productId)
.>нужно выбрать все возможные комбинации productId для всех Sale.
.>Т.е. скажем
.>Sale(1), у него SaleItem(1, 10), SaleItem(1, 11)
.>Sale(2), у него SaleItem(2, 10), SaleItem(2, 11)
.>Sale(3), у него SaleItem(3, 10), SaleItem(3, 11), SaleItem(3, 12)
.>Sale(4), у него SaleItem(4, 10), SaleItem(4, 13)
.>Здесь есть всего 3 комбинации продуктов [10,11], [10,11,12] и [10,13].
.>По моим ожиданиям комбинаций должно быть несколько десятков, а продаж —
.>сотни тысяч.
.>mssql 2000, если это имеет значение. Хотя хочется знать более менее
.>универсальное решение.
Интересная головоломка. Для ее решения можно использовать
реляционное деление без остатка.
Сначала создадим таблицу и заполним ее данными.
create table SaleItem(
SaleId int not null,
ProductId int not null,
primary key(SaleId, ProductId))
insert into SaleItem(SaleId, ProductId) values(1, 10)
insert into SaleItem(SaleId, ProductId) values(1, 11)
insert into SaleItem(SaleId, ProductId) values(2, 10)
insert into SaleItem(SaleId, ProductId) values(2, 11)
insert into SaleItem(SaleId, ProductId) values(3, 10)
insert into SaleItem(SaleId, ProductId) values(3, 11)
insert into SaleItem(SaleId, ProductId) values(3, 12)
insert into SaleItem(SaleId, ProductId) values(4, 10)
insert into SaleItem(SaleId, ProductId) values(4, 13)
insert into SaleItem(SaleId, ProductId) values(5, 10)
insert into SaleItem(SaleId, ProductId) values(5, 11)
insert into SaleItem(SaleId, ProductId) values(5, 12)
insert into SaleItem(SaleId, ProductId) values(6, 10)
insert into SaleItem(SaleId, ProductId) values(6, 13)
Теперь выполним запрос
select SaleId, ProductId
from SaleItem as s0
where not exists (
select s1.SaleId
from SaleItem as s1 left outer join
(select ProductId
from SaleItem
where SaleId = s0.SaleId) as s2
on s1.ProductId = s2.ProductId
where s1.SaleId < s0.SaleId
group by s1.SaleId
having count(s1.ProductId) = (select count(*)
from SaleItem
where SaleId = s0.SaleId) and
count(s2.ProductId) = (select count(*)
from SaleItem
where SaleId = s0.SaleId)
)
Результат запроса будет таким:
1 10
1 11
3 10
3 11
3 12
4 10
4 13
Для каждой повторяющейся комбинации продуктов оставлена одна комбинация
с минимальным SaleId.
Запрос не самый эффективный, но его можно оптимизировать.