修改查询.. [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)
运行以下查询以尝试将符号 - 'EUR / USD'中的CorEURUSD列复制到符号='GBP / USD
的结果CorEURUSD列中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]
它会抛出此错误。
Msg 4104,Level 16,State 1,Line 2 无法绑定多部分标识符“T.Time”。
我希望这更好,抱歉'群众混淆'请修改答案以匹配上述查询和表格,这应该是正确的。
答案 0 :(得分: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]
...但您没有提供我们使用的详细信息。
答案 1 :(得分: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): / p>
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';
真的没那么多修改,我只是改变了连接条件。
答案 2 :(得分:1)
三个问题:
T.[id] = [id]
条件没有多大意义,因为它等同于id = id
,这总是正确的。
以下查询应该有效,假设Symbol
是唯一的:
update TicksForex
set [CorEURUSD] = (
select CorEURUSD
from TicksForex
where Symbol = 'EUR/USD'
)
where Symbol = 'GBP/USD'
但是,根据您的错误提示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
值的来源。
我测试的方式:
填充表格有两行:
insert TicksForex
values('GBP/USD', 10, 20, 100)
insert TicksForex
values('EUR/USD', 30, 40, 200)
按原样运行查询:
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'.
添加了括号并删除了and T.[id] = [id]
:
update TicksForex
set CorEURUSD = (
select CorEURUSD
from TicksForex T
where Symbol = 'EUR/USD')
where Symbol = 'GBP/USD'
的工作。
添加了重复的行:
insert TicksForex
values('EUR/USD', 50, 60, 300)
再次编写脚本:
错误:
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.
从上面的回答中尝试了所有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
答案 3 :(得分: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' ;
答案 4 :(得分: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'