2014-11-11 2 views
0

Я пытаюсь обновить таблицу (Yahoostockdata) с информацией, извлеченной из другой таблицы (incomestatement), в зависимости от датыОбновления запрос: подзапрос возвращает более 1 значение

Yahoostockdata содержит Yahoo цены за день и я. d хотел бы добавить количество акций за дату в зависимости от самой актуальной информации, доступной в incomestatement за эту конкретную дату.

При выполнении запроса (без обновления) я получаю все номера, которые я хочу. UPDATE заявление, я получаю сообщение об ошибке: suquery возвращено более чем 1 значение.

Msg 512, Level 16, State 1, Line 1 Подзапрос возвратил более 1 значения. Это недопустимо, когда подзапрос следует =,! =, <, < =,>,> = или когда подзапрос используется как выражение. Заявление было прекращено.

Может ли кто-нибудь помочь мне решить эту проблему? Я уже посмотрел на связанные вопросы, но не смог найти ответа. Заранее спасибо. Ниже код я использую:

Update YahooStockData 
Set NumberOfShares = (Select [Weighted average shares outstanding (Diluted)] 
    from (Select *,ROW_NUMBER() over (partition by derived_1.MorningstarTicker, 
      derived_1.[date] order by derived_1.AsOfDate desc) as RN 
     from (Select Yahoostockdata.YahooTicker, IncomeStatement.MorningstarTicker, 
       yahoostockdata.[Date], AsOfDate, 
       Incomestatement.[Weighted average shares outstanding (Diluted)] 
       from IncomeStatement INNER JOIN 
        YahooStockData ON IncomeStatement.MorningstarTicker = YahooStockData.MorningstarTicker 
     Where YahooStockData.[Date] >= AsOfDate) as derived_1) as derived_2 
    Where RN = 1) 
+2

Есть ли что-то вы не понимаете, о «подзапрос возвращает более чем на 1 значение»? Подзапрос возвращает несколько строк. Вы можете наивно исправить это, используя 'top 1' в' select' или используя функцию агрегации, такую ​​как 'min()' или 'max()'. Однако вам может потребоваться некоторый контроль над тем, какое значение действительно выбрано. –

+0

Гордон, спасибо за ваш быстрый ответ. Top 1 и т. д., действительно, не решит его. В основном запрос дает мне точную копию всех строк, которые должны быть вставлены в таблицу yahoostockdata. Я был бы признателен за любые идеи или хорошие практики, как я могу это решить. – Xivan

ответ

0

Попробуйте

UPDATE A 
SET NumberOfShares = B.[Weighted average shares outstanding (Diluted)] 
FROM YahooStockData A 
     JOIN (SELECT [Weighted average shares outstanding (Diluted)], 
        derived_2.MorningstarTicker 
      FROM (SELECT *, 
          Row_number() OVER (partition BY derived_1.MorningstarTicker, derived_1.[date] 
           ORDER BY derived_1.AsOfDate DESC) AS RN 
        FROM (SELECT Yahoostockdata.YahooTicker, 
            IncomeStatement.MorningstarTicker, 
            yahoostockdata.[Date], 
            AsOfDate, 
            Incomestatement.[Weighted average shares outstanding (Diluted)] 
          FROM IncomeStatement 
            INNER JOIN YahooStockData 
              ON IncomeStatement.MorningstarTicker = YahooStockData.MorningstarTicker 
          WHERE YahooStockData.[Date] >= AsOfDate) AS derived_1) AS derived_2 
      WHERE RN = 1) B 
     ON A.MorningstarTicker = B.MorningstarTicker 
+0

Это отлично работает, THX. Мне нужно было добавить еще один столбец соединения (т. Е. A.date = B.date). К сожалению, запрос выполняется довольно медленно, поэтому любые идеи о том, как сделать это быстрее, будут приветствоваться. Теперь я добавил кластеризованный ключ на дату и тикер. – Xivan

1

Это может быть очищены и дальше, но я считаю, что это то, что вы после:

;WITH cte AS (Select MorningstarTicker,[Weighted average shares outstanding (Diluted)] 
       from (Select *,ROW_NUMBER() over (partition by derived_1.MorningstarTicker, 
          derived_1.[date] order by derived_1.AsOfDate desc) as RN 
         from (Select Yahoostockdata.YahooTicker, IncomeStatement.MorningstarTicker, 
            yahoostockdata.[Date], AsOfDate, 
            Incomestatement.[Weighted average shares outstanding (Diluted)] 
          from IncomeStatement 
          INNER JOIN YahooStockData ON IncomeStatement.MorningstarTicker = YahooStockData.MorningstarTicker 
          Where YahooStockData.[Date] >= AsOfDate 
          ) as derived_1 
        ) as derived_2 
       Where RN = 1) 
       ) 
UPDATE a 
SET a.NumberofShares = b.[Weighted average shares outstanding (Diluted)] 
FROM YahooStockData a 
JOIN cte b 
    ON a.MorningstarTicker = b.MorningstarTicker 

Я добавил MorningstartTicker в свой подзапроса и поставить весь бит в cte просто для того, чтобы сделать UPDATE с JOIN легче увидеть.

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

+0

Это отлично работает, THX. Мне нужно было добавить еще один столбец соединения (т. Е. A.date = B.date). К сожалению, запрос выполняется довольно медленно, поэтому любые идеи о том, как сделать это быстрее, будут приветствоваться. Теперь я добавил кластеризованный ключ на дату и тикер. В целом, работает ли CTE быстрее, чем предлагал Pradeep? – Xivan

+0

По-видимому, я могу отметить только 1 ответ как правильный, хотя оба работают. – Xivan

+0

@Xivan Я предполагаю, что план выполнения идентичен, я просто подумал, что cte облегчил просмотр обновления со структурой соединения. –

Смежные вопросы