新手SQL更新问题
修改后的查询。。[Id]列对于所有记录都是唯一的。。查询应将CorEURUSD的正确值返回到Symbol=EURUSD和Symbol=GBPUSD,其中[Time]=[Time]值新手SQL更新问题,sql,sql-server,sql-server-2005,tsql,Sql,Sql Server,Sql Server 2005,Tsql,修改后的查询。。[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, [Cor
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”复制到Symbol=“GBP/USD”的结果CorEURUSD列中
update Tck2
set CorEURUSD = (
select CorEURUSD
from Tck2 T
where Symbol = 'EUR/USD')
where Symbol = 'GBP/USD'
给出了这个错误
Msg 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,16级,状态1,第2行
无法绑定多部分标识符“T.Time”
我希望这样更好,为“大量混乱”感到抱歉,请修改答案以匹配上述查询和表,该查询和表应该是正确的。错误消息表示您的子查询:
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]
…但您没有提供详细信息供我们使用。只是基于松散规范的猜测,没有样本数据/预期结果
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 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' ;
三个问题:
T.[id]=[id]
条件没有多大意义,因为它相当于id=id
,这总是正确的
假设Symbol
是唯一的,下面的查询应该可以工作:
update TicksForex
set [CorEURUSD] = (
select CorEURUSD
from TicksForex
where Symbol = 'EUR/USD'
)
where Symbol = 'GBP/USD'
符号
不是唯一的
解决此问题的可能方法:
- 删除重复项。我相信这是最好的解决方案,但根据问题的信息无法确定
- 取第一个值:
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'.
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.
和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 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'.
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.
如果时间不完全匹配,可以执行以下操作:
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
现在我有你的问题了 以下是您的疑问:
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'
列中的值不超过一个,任何column@CraigJSte当前位置我倾向于相信错误,而不是你。但是我们没有人可以访问您的数据进行检查——只有您可以。我假设您的查询在子查询周围没有括号/括号是一个输入错误?我相信一个简单的内部连接和多个SELECT会起作用。我只是没有足够的SQL经验来做这件事。您能解释一下吗?我不明白你想做什么。您的条件`T.[id]=[id]`(这总是正确的,但我知道您的意思是更新表的[id]列)会导致表的同一行。因此,该行的[符号]可以是“英镑/美元”或“欧元/美元”。因此,只有修复了语法,才会更新任何行。请提供更多信息。我认为您的示例中可能有输入错误(除非当symbol='GBP/USD'时您只有一个[CorEURUSD]值)。您不能在[id]上有唯一的键,也不能在表中有两个具有相同id和[Symbol]两个不同值的项。这没有意义。嗨,@jj@maziar,很抱歉造成混乱,请参见上文…我已经包含了修改后的表和上面的查询,当我运行它时它返回了一个错误,请参见上文。。谢谢你的帮助help@CraigJSte-我以为我提供了与您标记为答案的相同的查询。然而,这比标记的答案早了一天。我只是好奇,为什么选择这个答案而不是我的答案呢?我不能肯定,但我认为@Aarons答案要么是在编辑完成后更快,要么是更简单、更容易理解,显然你投入了更多的工作和思考,值得称赞。。所以不管怎样,我可以试着分割赏金。@CraigJSte-你可以从编辑历史中看到,我在7月2日20:02更新了答案,你标记的答案在7月3日15:17更新。所以你标记的答案比较旧,也不太详细,这让我想知道你为什么选择这个答案。我已经修改了上面的查询和表格。。。[Time]列标识了一个与symbol和coreurusd匹配的列。。[id]不正确。见上文。。