2009-07-17 6 views
1

У меня есть набор записей данных запаса.SQL Select, исключая некоторые диапазоны

У меня также есть набор дат, для которых, хотя у меня могут быть данные, я не могу торговать акциями.

Вот пример DDL для установки:

create table #stock_data 
(
    symbol varchar (10) NOT NULL, 
    asof datetime NOT NULL, 
    price float NOT NULL 
) 
go 

insert into #stock_data values ('IBM', '7/1/09', 100) 
insert into #stock_data values ('IBM', '7/2/09', 100) 
insert into #stock_data values ('IBM', '7/3/09', 100) 
insert into #stock_data values ('IBM', '7/4/09', 100) 
insert into #stock_data values ('IBM', '7/5/09', 100) 
insert into #stock_data values ('IBM', '7/6/09', 100) 
insert into #stock_data values ('IBM', '7/7/09', 100) 
insert into #stock_data values ('IBM', '7/8/09', 100) 
insert into #stock_data values ('IBM', '7/9/09', 100) 

insert into #stock_data values ('MSFT', '7/1/09', 50) 
insert into #stock_data values ('MSFT', '7/2/09', 50) 
insert into #stock_data values ('MSFT', '7/3/09', 50) 
insert into #stock_data values ('MSFT', '7/4/09', 50) 
insert into #stock_data values ('MSFT', '7/5/09', 50) 
insert into #stock_data values ('MSFT', '7/6/09', 50) 
insert into #stock_data values ('MSFT', '7/7/09', 50) 
insert into #stock_data values ('MSFT', '7/8/09', 50) 
insert into #stock_data values ('MSFT', '7/9/09', 50) 
go 

create table #exclude_ranges 
(
    symbol varchar (10) NOT NULL, 
    asof_start datetime NOT NULL, 
    asof_end datetime NOT NULL 
) 
go 


insert into #exclude_ranges values ('IBM', '7/2/09', '7/2/09') 
insert into #exclude_ranges values ('IBM', '7/6/09', '7/8/09') 
insert into #exclude_ranges values ('MSFT', '7/1/09', '7/8/09') 

go 

И вот ВЫБРАТЬ я хочу. Я знаю, что должен быть какой-то умный способ сделать это, но я не могу вполне понять это .....

select * from #stock_data 
join ???? 
where ???? 

вернуть

('IBM', '7/1/09', 100) 
('IBM', '7/3/09', 100) 
('IBM', '7/4/09', 100) 
('IBM', '7/5/09', 100) 
('IBM', '7/9/09', 100) 
('MSFT', '7/9/09', 50) 

Так что магия идет в? ??? блоки?

ответ

5
SELECT * 
FROM #stock_data sd 
LEFT JOIN #exclude_ranges er 
    ON sd.symbol=er.symbol and sd.asof BETWEEN er.asof_start AND er.asof_end 
WHERE er.symbol IS NULL 
+1

Хех, я рыть обратную логику этого запроса. Присоединяйте элементы исключений к записям, которые они исключают, затем берем то, что осталось. – Dave

+0

Удивительный. Внешнее соединение FTW! –

1

Попробуйте это ...

select * from stock_data s 
left join exclude_ranges e 
    on e.symbol = s.symbol 
    and s.asof between e.asof_start and e.asof_end 
Where e.symbol is null 
Смежные вопросы