2011-06-25 175 views
2

修訂查詢.. [Id]列對所有記錄都是唯一的。查詢應該將CorEURUSD的正確值返回到Symbol = EURUSD和Symbol = GBPUSD,其中[Time] = [Time]值。新手SQL更新問題

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列複製運行下面的查詢 - 'EUR/USD' 轉化爲符號所產生的CorEURUSD列=「GBP/USD

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

給這個錯誤 消息512,級別16,狀態1,行1 子查詢返回多個值。當子查詢遵循=,!=,<,< =,>,> =或當子查詢用作表達式時,這是不允許的。 該聲明已被終止。

,當我使用這個版本..

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

它拋出這個錯誤。

Msg 4104,Level 16,State 1,Line 2 無法綁定多部分標識符「T.Time」。

我希望更好,抱歉'質量混亂'請修改答案以匹配上面的查詢和表格應該是正確的。

+0

我相信一個簡單的INNER JOIN與多個SELECT將起作用我只是沒有足夠的SQL經驗去做 – CraigJSte

+2

請問您能解釋一下嗎?我不明白你在做什麼。你的條件'T. [id] = [id]'(這總是正確的,但我知道你的意思是正在更新的表的[id]列)結果是表中的同一行。因此該行的[Symbol]可以是'GBP/USD'或'EUR/USD'。所以只有在修復語法時纔會更新行。請提供更多信息。 –

+2

我想你可能在你的例子中有一個錯字(除非符號='GBP/USD'時你只有一個[CorEURUSD]值)。 [id]上不能有唯一的鍵,並且在表中有兩個條目具有相同的ID和[Symbol]有兩個不同的值。這沒有意義。 –

回答

3

只是基於寬鬆的規格和沒有樣本數據/期望的結果的猜測。

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 根據調整後的規格。是否[時間]真的會成爲你進行這種更新的關鍵?聽起來很危險。無論如何,因爲[時間]是我可以根據敘述和樣本數據確定加入兩行的唯一方式,所以我認爲你的意思是(我也可以假設你只想更新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'; 

真的沒有那麼多修改真的,我只是改變了連接條件。

+0

我修改了上面的查詢和表格... [時間]列標識了一個匹配符號和coreurusd的列。[id]不正確。見上面.. – CraigJSte

3

錯誤消息是說,你的子查詢:

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] 

...但你沒有提供細節讓我們一起工作。

+0

列中不存在多個值,任何列 – CraigJSte

+1

@CraigJSte:我傾向於相信錯誤,而不是你。但是我們沒有人能夠訪問您的數據進行檢查 - 只有您可以。我認爲這是一個錯字,你的查詢沒有圍繞子查詢的括號/括號? –

0

首先,你需要括號周圍的子查詢,或者你將有另一個錯誤拋出:

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' ; 
1

三個問題:

  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' 
      
    • 採取minmaxavg等價值:

      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

我已經包括了修改後的表格和上面的查詢,並且在我看到上面的時候它返回了一個錯誤..感謝您的幫助 – CraigJSte

+0

@CraigJSte - 我更新了答案。 –

+0

@CraigJSte - 我認爲我提供了與您標記爲答案相同的查詢。但是,這比標記的答案早了一天。只是好奇,在我的選擇這個答案的理由是什麼? –

0

現在,我得到了你的問題

這是你的查詢:

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'