Начинающий вопрос об обновлении SQL - PullRequest
2 голосов
/ 25 июня 2011

Пересмотренный запрос. Столбец [Id] уникален для всех записей. Запрос должен возвращать правильное значение CorEURUSD для символов Symbol = EURUSD и Symbol = GBPUSD, где значения [Time] = [Time].

 CREATE TABLE [dbo].[Tck2](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Symbol] [varchar](35) NULL,
[Time] [datetime] NULL,
[CorEURUSD] [decimal](14, 10) NULL,
[CorEURUSD2] [decimal](14, 10) NULL
  ) ON [PRIMARY]


 INSERT [VT7STAB1].[dbo].[Tck2] ([Symbol],[Time],[CorEURUSD],[CorEURUSD2]) VALUES('EUR/USD', '2011-07-01 12:04:28.000', 0.8229, 0.6488)
 INSERT [VT7STAB1].[dbo].[Tck2] ([Symbol],[Time],[CorEURUSD],[CorEURUSD2]) VALUES('EUR/USD', '2011-07-01 12:26:17.000', 0.9427, 0.6558)
 INSERT [VT7STAB1].[dbo].[Tck2] ([Symbol],[Time],[CorEURUSD],[CorEURUSD2]) VALUES('EUR/USD', '2011-07-01 12:58:34.000', 0.7713, 0.5267)
 INSERT [VT7STAB1].[dbo].[Tck2] ([Symbol],[Time],[CorEURUSD],[CorEURUSD2]) VALUES('GBP/USD', '2011-07-01 12:04:28.000', 0, 0)
 INSERT [VT7STAB1].[dbo].[Tck2] ([Symbol],[Time],[CorEURUSD],[CorEURUSD2]) VALUES('GBP/USD', '2011-07-01 12:26:17.000', 0, 0)
 INSERT [VT7STAB1].[dbo].[Tck2] ([Symbol],[Time],[CorEURUSD],[CorEURUSD2]) VALUES('GBP/USD', '2011-07-01 12:58:34.000', 0, 0)

Выполнение следующего запроса в попытке скопировать столбец CorEURUSD из Symbol - 'EUR / USD' в результирующий столбец CorEURUSD для Symbol = 'GBP / USD

update Tck2
set CorEURUSD = (
     select CorEURUSD
     from Tck2 T 
     where Symbol = 'EUR/USD')
 where Symbol = 'GBP/USD'

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

и когда я использовал эту ревизию ..

update Tck2
set CorEURUSD = (
     select CorEURUSD
     from Tck2 T 
     where Symbol = 'EUR/USD')
 where Symbol = 'GBP/USD'
 and T.[Time] = [Time]

Выдает эту ошибку.

Сообщение 4104, уровень 16, состояние 1, строка 2 Не удалось связать многокомпонентный идентификатор «T.Time».

Я надеюсь, что это лучше, извините за «массовую путаницу», пожалуйста, пересмотрите ответы, чтобы соответствовать приведенному выше запросу и таблице, которая должна быть правильной.

Ответы [ 5 ]

3 голосов
/ 02 июля 2011

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

UPDATE t
    SET t.[CorEURUSD] = x.[CorEURUSD] 
    FROM dbo.TicksForex AS t
    INNER JOIN dbo.TicksForex AS x
    ON t.[id] = x.[id]
    WHERE 
        t.[Symbol] = 'GBP/USD'
        AND x.[Symbol] = 'EUR/USD';

РЕДАКТИРОВАТЬ 2011-07-03 На основе пересмотренных спецификаций.Действительно ли [Time] станет вашим ключом для такого типа обновлений?Звучит рискованно.В любом случае, поскольку [Время] было единственным способом, который я мог решить объединить две строки на основе ваших описательных и типовых данных, я предполагаю, что вы имеете в виду именно это (и я также могу предположить, что вы хотите обновить только CorEURUSD, а не CorEURUSD2):

UPDATE t
    SET t.[CorEURUSD] = x.[CorEURUSD]
    FROM dbo.Tck2 AS t
    INNER JOIN dbo.Tck2 AS x
    ON t.[Time] = x.[Time]
    WHERE t.Symbol = 'GBP/USD'
    AND x.Symbol = 'EUR/USD';

На самом деле это не так уж и сложно, я просто изменил условие соединения.

3 голосов
/ 25 июня 2011

В сообщении об ошибке говорится, что ваш подзапрос:

SELECT [CorEURUSD] 
  FROM TicksForex T 
 WHERE [Symbol] = 'EUR/USD' 
   AND T.[id] = [id]

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

SELECT MAX([CorEURUSD])
  FROM TicksForex T 
 WHERE [Symbol] = 'EUR/USD' 
   AND T.[id] = [id]

... или самое низкое:

SELECT MIN([CorEURUSD])
  FROM TicksForex T 
 WHERE [Symbol] = 'EUR/USD' 
   AND T.[id] = [id]

... но вы не предоставили нам подробную информациюработать с.

1 голос
/ 02 июля 2011

Три проблемы:

  1. Отсутствует скобка.
  2. T.[id] = [id] условие не имеет большого смысла, так как оно эквивалентно id = id, что всегда верно.

    Запрос ниже должен работать при условии, что Symbol уникален:

    update TicksForex 
    set [CorEURUSD] = (
            select CorEURUSD 
            from TicksForex 
            where Symbol = 'EUR/USD'
        )
    where Symbol = 'GBP/USD'
    
  3. Однако из того, что говорит ваша ошибка, Symbol не уникален.

    Возможные способы исправить это:

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

      update TicksForex 
      set CorEURUSD = (
          select top 1 CorEURUSD
          from TicksForex T 
          where Symbol = 'EUR/USD')
      where Symbol = 'GBP/USD'
      
    • дубль min, max, avg и др. Значение:

      update TicksForex 
      set CorEURUSD = (
          select max(CorEURUSD)
          from TicksForex T 
          where Symbol = 'EUR/USD')
      where Symbol = 'GBP/USD'
      

    Как правило, вам нужно либо убедиться, что нет дубликатов, либо указать, какая именно дублирующаяся строка должна использоваться в качестве источника значения CorEURUSD.


То, как я это проверял:

  1. Создана таблица с использованием вашего скрипта.
  2. заполненный стол из двух строк:

    insert TicksForex
    values('GBP/USD', 10, 20, 100)
    
    insert TicksForex
    values('EUR/USD', 30, 40, 200)
    
  3. Запустил запрос как есть:

    update TicksForex 
    set CorEURUSD = 
        select CorEURUSD
        from TicksForex T 
        where Symbol = 'EUR/USD' and T.[id] = [id]
    where Symbol = 'GBP/USD'
    

    Ошибка:

    Msg 156, Level 15, State 1, Line 3
    Incorrect syntax near the keyword 'select'.
    Msg 156, Level 15, State 1, Line 6
    Incorrect syntax near the keyword 'where'.
    
  4. Добавлены скобки и удалены and T.[id] = [id]:

    update TicksForex 
    set CorEURUSD = (
        select CorEURUSD
        from TicksForex T 
        where Symbol = 'EUR/USD')
    where Symbol = 'GBP/USD'
    

    работал.

  5. Добавлена ​​повторяющаяся строка:

    insert TicksForex
    values('EUR/USD', 50, 60, 300)
    
  6. Запустил скрипт снова:

    Ошибка:

    Msg 512, Level 16, State 1, Line 1
    Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
    
  7. Перепробовал все 3 решения из моего ответа выше - сработало.

[РЕДАКТИРОВАТЬ] После предоставления данных образца.

Если время абсолютно совпадает, вы можете сделать это:

update t1 
set CorEURUSD = t2.CorEURUSD, CorEURUSD2 = t2.CorEURUSD2
from Tck2 t1 
    join Tck2 t2 on
        t1.Time = t2.Time
where 
    t1.Symbol = 'GBP/USD' and
    t2.Symbol = 'EUR/USD' 

Если время не полностью совпадает, вы можете сделать это:

;with 
cte1 as
(
    select *, row_number() over (order by Time) RowNumber
    from Tck2
    where Symbol = 'EUR/USD'
),
cte2 as
(
    select *, row_number() over (order by Time) RowNumber
    from Tck2
    where Symbol = 'GBP/USD'
)
update cte2
set CorEURUSD = cte1.CorEURUSD, CorEURUSD2 = cte1.CorEURUSD2
from cte1 
    join cte2 on
        cte1.RowNumber = cte2.RowNumber
0 голосов
/ 03 июля 2011

Теперь я получил ваш вопрос

вот ваш запрос:

update a
set a.[CorEURUSD] = b.[CorEURUSD]
from [dbo].[Tck2] as a
join [dbo].[Tck2] as b on a.[Time] = b.[Time]
where a.[Symbol] = 'GBP/USD' and b.[Symbol]= 'EUR/USD'
0 голосов
/ 02 июля 2011

Во-первых, вам необходимо заключить скобки в подзапрос, иначе возникнет еще одна ошибка:

UPDATE TicksForex 
   SET [CorEURUSD] = ( SELECT [CorEURUSD] 
                        FROM TicksForex T 
                       WHERE [Symbol] = 'EUR/USD' 
                     )
WHERE [Symbol] = 'GBP/USD' ;

Во-вторых, ошибка предполагает, что с [Symbol] = 'EUR/USD' имеется более одной строки.Этот запрос покажет число больше 1:

SELECT COUNT(*) 
FROM [TicksForex] 
WHERE [Symbol] = 'EUR/USD' ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...