Требуется получить список продаж и возвратов, при том продажи должны учитывать продавцов, склады и сами товары, а возвраты - только склады и товары, но продавцы могут быть любыми. При этом в выборку должны попасть только продавцы, продавшие товаров на определённую сумму, учитывая возвраты.
Пример:
Товар А со стоимостью 10 продан трижды одним продавцом с одного склада, и один раз был возвращён через другого продавца, сумма продаж до возврата удовлетворяла требования выборки, но после возврата перестала удовлетворять и в результатах ни одного из товаров, проданных этим продавцом в складе не должно быть видно, как и возвращённого другому продавцу товара.
declare @Sales table (SalePerson varchar(100), WarehouseCode varchar(3), Amount float, Item varchar(50), Qty int);
declare @Refunds table (RefundPerson varchar(100), WarehouseCode varchar(3), Amount float, Item varchar(50), Qty int);
insert into @Sales (SalePerson, WarehouseCode, Amount, Item, Qty) values ('Foo', '001', 10, 'item A', 1);
insert into @Sales (SalePerson, WarehouseCode, Amount, Item, Qty) values ('Foo', '002', 10, 'item A', 1);
insert into @Sales (SalePerson, WarehouseCode, Amount, Item, Qty) values ('Foo', '003', 10, 'item A', 1);
insert into @Sales (SalePerson, WarehouseCode, Amount, Item, Qty) values ('bar', '001', 10, 'item A', 1);
insert into @Sales (SalePerson, WarehouseCode, Amount, Item, Qty) values ('bar', '001', 10, 'item A', 1);
insert into @Sales (SalePerson, WarehouseCode, Amount, Item, Qty) values ('bar', '002', 10, 'item A', 1);
insert into @Sales (SalePerson, WarehouseCode, Amount, Item, Qty) values ('bar', '001', 10, 'item A', 1);
insert into @Sales (SalePerson, WarehouseCode, Amount, Item, Qty) values ('bar', '003', 10, 'item A', 1);
insert into @Sales (SalePerson, WarehouseCode, Amount, Item, Qty) values ('bar', '001', 20, 'item B', 1);
insert into @Sales (SalePerson, WarehouseCode, Amount, Item, Qty) values ('bar', '002', 20, 'item B', 1);
insert into @Refunds (RefundPerson, WarehouseCode, Amount, Item, Qty) values ('abc', '003', -10, 'item A', 1);
insert into @Refunds (RefundPerson, WarehouseCode, Amount, Item, Qty) values ('Foo', '001', -10, 'item A', 1);
-- даже эта выборка не верна, потому что SalePerson меня реально интересует только для Sales, в Refunds может быть другой. А ещё в ней отсутствуют реальные количества товаров и цены:
select Person, WarehouseCode, Item from
(
select SalePerson as Person, WarehouseCode, Amount, Item, Qty from @Sales
union all
select RefundPerson as Person, WarehouseCode, Amount, Item, Qty from @Refunds
) as X
group by Person, Item, WarehouseCode
having sum(Qty*Amount) >= 20
И не хотелось бы переусложнять запрос, потому что то, что здесь выглядит как @Sales и @Refunds на самом деле тоже немаленькие селекты. Что-то мне подсказывает, что должно быть какое-то изящное решение, но я его, увы, не вижу :(