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

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

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

Сообщение 512, уровень 16, состояние 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)
0
Xivan 11 Ноя 2014 в 19:57
2
Есть ли что-то, чего вы не понимаете в том, что «подзапрос возвращает более 1 значения»? Подзапрос возвращает несколько строк. Вы можете наивно исправить это, используя top 1 в select или используя функцию агрегации, такую ​​как min() или max(). Однако вам может понадобиться некоторый контроль над тем, какое значение фактически выбрано.
 – 
Gordon Linoff
11 Ноя 2014 в 20:01
Гордон, спасибо за быстрый ответ. Top 1 и т. д. действительно не решит эту проблему. В основном запрос дает мне точную копию всех строк, которые должны быть вставлены в таблицу yahoostockdata. Я был бы признателен за любые идеи или передовой опыт, как я могу решить эту проблему.
 – 
Xivan
11 Ноя 2014 в 20:05

2 ответа

Лучший ответ

Попробуй это

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
Pரதீப் 11 Ноя 2014 в 20:16
Это отлично работает, спасибо. Мне нужно было только добавить еще один столбец соединения (т.е. A.date = B.date). К сожалению, запрос выполняется довольно медленно, поэтому приветствуются любые идеи о том, как его ускорить. Теперь я добавил сгруппированный ключ по дате и бегущей строке.
 – 
Xivan
12 Ноя 2014 в 09:44

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

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

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

1
Hart CO 11 Ноя 2014 в 20:21
Это отлично работает, спасибо. Мне нужно было только добавить еще один столбец соединения (т.е. A.date = B.date). К сожалению, запрос выполняется довольно медленно, поэтому приветствуются любые идеи о том, как его ускорить. Теперь я добавил сгруппированный ключ по дате и бегущей строке. В общем, CTE работает быстрее, чем то, что предложил Pradeep?
 – 
Xivan
12 Ноя 2014 в 09:44
По-видимому, я могу отметить только 1 ответ как правильный, хотя оба работают.
 – 
Xivan
12 Ноя 2014 в 09:45
Я предполагаю, что план выполнения идентичен, я просто подумал, что cte упрощает просмотр обновления со структурой соединения.
 – 
Hart CO
12 Ноя 2014 в 17:26