2017-04-12 245 views
3

嗨我想根据第3列中的内容计算2列值。根据第3列值计算2列

下面的错误代码将数据类型varchar转换为数字时出错。

我相信它试图将货币列设置为新值而不是测试。

任何人都可以帮助我的语法。

谢谢。

SELECT dbo.ORDR.DocTotal, 
     dbo.ORDR.DocTotalFC, 
     test = case 


when dbo.RDR1.Currency = 'GBP' then dbo.ORDR.DocTotal - dbo.ORDR.VatSum 
when dbo.RDR1.Currency = 'USD' then dbo.ORDR.DocTotalFC - dbo.ORDR.VatSumFC 
when dbo.RDR1.Currency = 'EUR' then dbo.ORDR.DocTotalFC - dbo.ORDR.VatSumFC 

else 'other' 
end 


FROM dbo.RDR1 INNER JOIN 
        dbo.ORDR ON dbo.RDR1.DocEntry = dbo.ORDR.DocEntry 
+0

你有样品数据和所需的输出? – Tanner

+0

在猜测,我会说'DocTotal'或'VatSum'不是数字数据类型,因此在子句中的减法失败....但你需要向我们展示模式和数据,否则我们'重新猜测。 – Tanner

+1

您不能随意决定将此列中的值设置为varchar,而对于其他行,则为varchar。您必须为所有行中的给定列使用单一数据类型。你的情况表达式正在做数学或返回一个字符串文字。您需要在那里返回NULL或强制您的计算值为varchar。 –

回答

7

与CASE表达式

else 'other' 

的其他部分,因为你的情况表达的问题返回其他场景值的一些整数类型,但在其他部分你是它与以前的不兼容返回字符串值值。尝试用一些整数值替换其他条件作为默认值

2

错误是由您的其他条件造成的,我们将返回other。列中的值看起来是money或某种形式的decimal(x,x)

我们不能混合选定列中的数据类型。因此,我们不能在case语句中混合类型,因为它返回单个列。

理想情况下,您应该将其他条件设置为像0.0这样的货币金额,以便不会出错并保持一致。

未来,您的caseelse部分是寻找这些错误的好地方,正如您根据您的意见所看到的那样。这通常是开发人员尝试混合数据类型的地方。

如果必须退回other,投你的其他返回值更改为varchar:

SELECT dbo.ORDR.DocTotal, 
     dbo.ORDR.DocTotalFC, 
     test = case 


when dbo.RDR1.Currency = 'GBP' then cast((dbo.ORDR.DocTotal - dbo.ORDR.VatSum) as varchar(255)) 
when dbo.RDR1.Currency = 'USD' then cast((dbo.ORDR.DocTotalFC - dbo.ORDR.VatSumFC) as varchar(255)) 
when dbo.RDR1.Currency = 'EUR' then cast((dbo.ORDR.DocTotalFC - dbo.ORDR.VatSumFC) as varchar(255)) 

else 'other' 
end 


FROM dbo.RDR1 INNER JOIN 
        dbo.ORDR ON dbo.RDR1.DocEntry = dbo.ORDR.DocEntry 
+1

是的,我删除了其他评论,因为它不需要在那里,它是从我复制的其他代码中遗留下来的,它正凝视着我的脸,我错过了它。感谢您的帮助。 –

+0

良好的呼叫!这可能是最好的事情。返回列的实际数据类型是理想的。 – RexMaison

+0

由于这现在正在使用select语句,我希望更新表中的实际列。 'dbo.ORDR.DiscSum',请您指出我改变剧本的正确方向,我可以在一张桌子上做,但我不确定如何加入2张桌子。 –

1

明白了。谢谢你的链接:)

update dbo.ORDR 
set DiscSum = case 
when dbo.RDR1.Currency = 'GBP' then dbo.ORDR.DocTotal - dbo.ORDR.VatSum 
when dbo.RDR1.Currency = 'USD' then dbo.ORDR.DocTotalFC - dbo.ORDR.VatSumFC 
when dbo.RDR1.Currency = 'EUR' then dbo.ORDR.DocTotalFC - dbo.ORDR.VatSumFC 

end 


FROM   dbo.RDR1 INNER JOIN 
        dbo.ORDR ON dbo.RDR1.DocEntry = dbo.ORDR.DocEntry