Admitedly not thoroughly tested - but how about using a CTE, and ROWNUMBER() to do this in two steps
1) Identify all the nextsubseqent hi's for each row
2) any row that immediate next row has a subsequent high less than the current row - then current row must be a local max.
or something like that:
begin
DECLARE @highTable as table (high bigint, day date)
declare @securityid int,
@start datetime,
@end datetime
set @start = '1-1-2010'
set @end = '2-1-2010'
select @securityid = id from security where riccode = 'MSFT.OQ' ;
with highsandlows_cte as (
SELECT
ROW_NUMBER() over (order by day) i
, high
, day
, (select top 1 day from quotes nextHi where nextHi.high > today.high and nextHi.day >= today.day and nextHi.securityId = today.securityId order by day asc) nextHighestDay
FROM
quotes today
WHERE
today.securityid = @securityid )
select
*
, (Coalesce((select 1 from highsandlows_cte t2 where t1.i + 1 = t2.i and t1.nextHighestDay > t2.nextHighestDay),0)) as isHigh
from
highsandlows_cte t1
order by
day
end
ok the above is wrong - this appears to be more on track:
begin
DECLARE @highTable as table (high bigint, day date)
declare @securityid int,
@start datetime,
@end datetime
set @start = '1-1-2010'
set @end = '2-1-2010'
select @securityid = id from security where riccode = 'MSFT.OQ' ;
with highsandlows_cte as (
SELECT
ROW_NUMBER() over (order by day) i
, high
, day
, low
FROM
quote today
WHERE
today.securityid = @securityid and today.day > convert(varchar(10), @start, 111) and convert(varchar(10), @end, 111) >today.day)
select
cur.day
, cur.high
, cur.low
, case when ((cur.high > prv.high or prv.high IS null)and(cur.high > nxt.high or nxt.high is null)) then 1 else 0 end as isLocalMax
, case when ((cur.low < prv.low or prv.low IS null)and(cur.low < nxt.low or nxt.low is null)) then 1 else 0 end as isLocalMin
from
highsandlows_cte cur left outer join highsandlows_cte nxt
on cur.i + 1 = nxt.i
left outer join highsandlows_cte prv
on cur.i - 1 = prv.i
order by
cur.day
end
Get issues with duplicates (highs / lows) though...