我正在努力构建在存储过程中构造sql select查询所需的逻辑。我的数据库与股市数据一起使用。我有一张2012年交易日期表,一个股票代码表,以及这些符号和交易日期的每日定价数据表,通过网络服务。我正在尝试使用我正在努力的select查询中的组件编写Web服务地址字符串。
下面的第一个程序足以返回包含字段“符号,开始日期,结束日期”的记录,其中包含开始日期和结束日期,表示每个符号所需的最早和最新缺失数据点:
ALTER PROCEDURE dbo.sprocSymbsDatesForHistoricalPricingVoll
AS
DECLARE @NxtAvailableDataDownloadDate date
SET @NxtAvailableDataDownloadDate = dbo.NextAvailableDataDownloadDate()
SELECT Symbol, MIN(TradingDate), Max(TradingDate)
FROM (SELECT Symbol, TradingDate
FROM (SELECT tblSymbolsMain.Symbol, tblTradingDays.TradingDate
FROM tblSymbolsMain CROSS JOIN
tblTradingDays
WHERE (tblTradingDays.TradingDate <= @NxtAvailableDataDownloadDate)) AS T1
WHERE (NOT EXISTS
(SELECT TradeDate, Symbol
FROM tblDailyPricingAndVol
WHERE (TradeDate = T1.TradingDate) AND (Symbol = T1.Symbol)))) t GROUP BY Symbol ORDER BY Symbol
这可以很好地交叉加入所有交易日期的所有股票代码,并返回不在我的定价表中的股票代码。精细。我的问题是,虽然我可能会回到一行,这样我就可以从每个符号表中获得该表的最小和最大日期:
AAPL, 1/1/12, 1/10/12
我的定价表中可能已经包含该日期范围内的一些必需数据点,例如:
AAPL, 1/5/12- 1/9/12
在这种情况下,我想回到的是:
AAPL, 1/1/12, 1/4/12
AAPL, 1/10/12, 1/10/12
而不是上面带有股票代码的第一个例子。我可以通过循环过程代码方式轻松地做到这一点,但我希望看到这在db端实现。有任何想法吗?提前谢谢......
答案 0 :(得分:1)
递归是你的答案。以下是如何使用内部select语句并将其转换为范围行。 SQL 2005或更高版本中提供了递归,因此我希望它适合您。
create table dates (dt datetime null)
go
insert into dates(dt) values('1/1/2012')
insert into dates(dt) values('1/2/2012')
insert into dates(dt) values('1/3/2012')
insert into dates(dt) values('1/4/2012')
insert into dates(dt) values('1/10/2012')
go
--Show raw data
select * from dates
go
--Define the recursive query
WITH RecursiveQuery (anchorDate, dt)
AS
(
-- Anchor member of recursive query
SELECT
anchorDate=dt,
dt
FROM
dates AS e
WHERE
NOT EXISTS(select 1 from dates where dateadd(day,-1,e.dt)=dt)
UNION ALL
-- Recursive member (notice join to RecursiveQuery)
SELECT
anchorDate=d.anchorDate,
e.dt
FROM
dates AS e
INNER JOIN RecursiveQuery AS d ON e.dt = dateadd(day,1,d.dt)
)
--Final Join
select
startdt=anchorDate,enddt=max(dt)
FROM
RecursiveQuery
group by anchorDate
order by anchorDate