SQL Server为所需的存储过程选择查询帮助

时间:2012-02-07 04:07:07

标签: sql-server

我正在努力构建在存储过程中构造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端实现。有任何想法吗?提前谢谢......

1 个答案:

答案 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

enter image description here

相关问题