Sql Server - объединение подзапросов с использованием вычисляемых полей - PullRequest
4 голосов
/ 20 мая 2011

Я пытаюсь рассчитать процентное изменение цены между днями.Поскольку дни не являются последовательными, я встраиваю в запрос вычисляемое поле, которое сообщает мне, какой это относительный день (день 1, день 2 и т. Д.).Чтобы сравнить сегодняшний день со вчерашним днем, я сместил вычисленный номер дня на 1 в подзапросе.я хочу присоединиться к внутреннему и внешнему запросу в вычисленный относительный день.Код, который я придумал:

SELECT TOP 11 
       P.Date,
       (AVG(P.SettlementPri) - PriceY) / PriceY as PriceChange, 
       P.Symbol,
       (RANK() OVER (ORDER BY P.Date desc)) as dayrank_Today
FROM OTE P
  JOIN (SELECT TOP 11 
               C.Date, 
               AVG(SettlementPri) as PriceY, 
               (RANK() OVER (ORDER BY C.Date desc))+1 as dayrank_Yest
          FROM OTE C
         WHERE C.ComCode = 'C-' 
      GROUP BY c.Date) C ON dayrank_Today = C.dayrank_Yest
WHERE P.ComCode = 'C-' 
GROUP BY P.Symbol, P.Date 

Если я пытаюсь выполнить запрос, я получаю сообщение об ошибке, указывающее, что dayrank_Today является недопустимым столбцом.Я попытался переименовать его, квалифицировать, кричать об этом, и я приседаю.Все еще ошибка.

Ответы [ 3 ]

3 голосов
/ 25 апреля 2013

У меня была такая же проблема, я нашел эту ветку и нашел решение, поэтому решил опубликовать ее здесь.

Вместо использования имени столбца в качестве параметра для ON , скопируйте оператор, который дал вам имя colmun в первую очередь:

заменить:

ON dayrank_Today = C.dayrank_Yest

с:

ON (RANK() OVER (ORDER BY Date desc)) = C.dayrank_Yest 

Конечно, вы недовольны Богами Программирования, нарушая DRY , но вы можете быть прагматичными и упомянуть дублирование в комментариях, которое должно успокоить их гнев до легкого ворчания.

2 голосов
/ 20 мая 2011

Вы не можете выбрать вычисляемый столбец, а затем использовать его в объединении.Вы можете использовать CTE, с которыми я не очень хорошо знаком, или вы можете просто сделать выбор таблицы следующим образом:


SELECT 
     P.Date,       
     (AVG(AvgPrice) - C.PriceY) / C.PriceY as PriceChange, 
     P.Symbol,       
     P.dayrank_Today FROM
(SELECT TOP 11 
       ComCode,
       Date,
       AVG(SettlementPri) as AvgPrice,
       Symbol,
       (RANK() OVER (ORDER BY Date desc)) as dayrank_Today
FROM OTE WHERE ComCode = 'C-') P 
  JOIN (SELECT TOP 11 
               C.Date, 
               AVG(SettlementPri) as PriceY, 
               (RANK() OVER (ORDER BY C.Date desc))+1 as dayrank_Yest
          FROM OTE C
         WHERE C.ComCode = 'C-' 
      GROUP BY c.Date) C ON dayrank_Today = C.dayrank_Yest 
GROUP BY P.Symbol, P.Date 


1 голос
/ 21 мая 2011

Если возможно, рассмотрите возможность использования CTE, поскольку это делает его очень простым. Примерно так:

With Raw as
(
    SELECT TOP 11 C.Date,
    Avg(SettlementPri) As PriceY,
    Rank() OVER (ORDER BY C.Date desc) as dayrank
    FROM OTE C WHERE C.Comcode = 'C-'
    Group by C.Date
) 

select today.pricey as todayprice ,
yesterday.pricey as yesterdayprice,
(today.pricey - yesterday.pricey)/today.pricey * 100 as percentchange 
from Raw today
left outer join Raw yesterday on today.dayrank = yesterday.dayrank + 1

Очевидно, что это не включает символ, но это может быть включено довольно легко. Если использование синтаксиса «С» не подходит, вы также можете использовать вычисляемые поля с Outer Apply http://technet.microsoft.com/en-us/library/ms175156.aspx

Хотя CTE будет означать, что вам нужно написать расчет цены только один раз, что намного чище

Приветствия

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...