Sql Server CTE «Не удалось связать идентификатор из нескольких частей». - PullRequest
2 голосов
/ 04 января 2012

На мой последний вопрос об этом же самом cte-запросе ответили так быстро, что я решил отослать следующий от вас, гуру SQL. Если бы я мог просмотреть мою основную логику, а затем показать мой код и синтаксическую ошибку, любая помощь будет принята с благодарностью.

У меня есть три таблицы для системы торговли акциями: таблица символов: как следует из названия, это список символов тикера, таблица ежедневных цен / объемов: опять же, как описано, и каждая запись имеет поле даты и символ поле, а также информация о ценах и, наконец, таблица торговых дат: ссылка на все торговые даты в нашем запросе.

Я хотел бы вернуть набор записей с двумя полями: символ и дата. Пара представляет все торговые даты и символы, которые не имеют соответствующих данных цены / объема для этого символа в таблице объема цен. Есть смысл? По моему запросу я получаю сообщение об ошибке: «Не удалось связать многокомпонентный идентификатор« 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 Ответ

9 голосов
/ 04 января 2012

Это:

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
    )
...