Sql Server CTE“无法绑定多部分标识符”。

时间:2012-01-03 23:24:27

标签: sql-server common-table-expression

我对同一个cte查询的最后一个问题得到了如此迅速的回答,我以为我会从你的sql大师那里反弹下一个。如果我可以查看我的基本逻辑,然后显示我的代码和语法错误,将非常感谢任何帮助..

我有一个股票交易系统的三个表:一个符号表:顾名思义它是一个股票代码列表,每日定价/交易量表:再次,如上所述,每个记录都有一个日期字段和符号字段以及定价信息,最后是交易日期表:我们查询中所有交易日期的参考。

我想返回一个包含两个字段的记录集:符号和日期。该对代表所有交易日期和符号,这些交易日期和符号在定价量表中没有该符号的相应定价/ vol数据。合理?在我的查询中,我收到错误消息:“多部分标识符”Symb.Symbol“无法绑定。”这是我的cte查询:

WITH Symb AS
(
     SELECT Symbol
     FROM tblSymbolsMain
),

DatesNotNeeded AS
(
     SELECT Date
     FROM tblDailyPricingAndVol
     WHERE (tblDailyPricingAndVol.Symbol = Symb.Symbol)
),

WideDateRange AS
(
     SELECT TradingDate
     FROM tblTradingDays
     WHERE (TradingDate >= dbo.NextAvailableDataDownloadDateTime()) AND (TradingDate <= dbo.LatestAvailableDataDownloadDateTime())
),

DatesNeeded AS
(
     SELECT TradingDate
     FROM WideDateRange wdr
     WHERE NOT EXISTS (SELECT * FROM DatesNotNeeded)
)

SELECT Symb.Symbol, DatesNeeded.TradingDate
FROM Symb CROSS JOIN DatesNeeded

1 个答案:

答案 0 :(得分:9)

此:

DatesNotNeeded AS
(
     SELECT Date
     FROM tblDailyPricingAndVol
     WHERE (tblDailyPricingAndVol.Symbol = Symb.Symbol)
),

需要这样:

DatesNotNeeded AS
(
     SELECT Date
     FROM tblDailyPricingAndVol inner join Symb on
         tblDailyPricingAndVol.Symbol = Symb.Symbol
),

但是你的查询仍然不起作用,因为:

DatesNeeded AS
(
     SELECT TradingDate
     FROM WideDateRange wdr
     WHERE NOT EXISTS (SELECT * FROM DatesNotNeeded)
)

需要这样:

DatesNeeded AS
(
     SELECT TradingDate
     FROM WideDateRange wdr
     WHERE NOT EXISTS (SELECT * FROM DatesNotNeeded d where d.Date = wdr.TradingDate)
)

但实际上,你可以在没有CTE的情况下做到这一点,就像这样:

select
    sm.Symbol,
    tb.TradingDate
from
    tblSymbolsMain sm
    cross join tblTradingDays tb
    left join tblDailyPricingAndVol dp on
        sm.Symbol = dp.Symbol 
        and tb.TradingDate = dp.Date
where
    tb.TradingDate between 
        dbo.LatestAvailableDataDownloadDateTime()
        and dbo.NextAvailableDataDownloadDatetime()
    and dp.Date is null

此查询会抓取tblSymbolsMain中的所有符号以及tblTradingDays的上一个和下一个可用日期之间的所有日期。然后它在left join上执行tblDailyPricingAndVol并过滤掉找到匹配项的任何行。

您也可以使用not exists代替left join,我认为这也更清晰:

select
    sm.Symbol,
    tb.TradingDate
from
    tblSymbolsMain sm
    cross join tblTradingDays tb
where
    tb.TradingDate between 
        dbo.LatestAvailableDataDownloadDateTime() 
        and dbo.NextAvailableDataDownloadDatetime()
    and not exists (
        select
            1
        from
            tblDailyPricingAndVol dp
        where
            dp.Symbol = sm.Symbol
            and dp.Date = tb.TradingDate
    )