列值是需要转换为十进制的varchar。列名采用日期格式。 sql服务器

Posted

技术标签:

【中文标题】列值是需要转换为十进制的varchar。列名采用日期格式。 sql服务器【英文标题】:column value is varchar which needs to be converted to decimal. column name is in date format. sql server 【发布时间】:2020-07-09 13:49:34 【问题描述】:

我有一个表 tblSample,其中列名称为日期格式值,即 [202007]、[202006]---[202001],数据类型为 varchar

我想用 [202006]-[202005] 更新 tblSample 的另一列 (X),用 [202005]-[202004] 更新列 (Y)。 我正在使用下面的查询,它为所有记录提供输出为 1(tblSample 中大约有 50 条记录)。

    UPDATE tblSample          
    SET
    X = CAST(ISNULL(SELECT LEFT(CONVERT(varchar, DATEADD(month, -3, GETDATE(), 112), 6)), 0) AS DECIMAL(18,2)) - CAST(ISNULL((SELECT LEFT(CONVERT(varchar, DATEADD(month, -4, GETDATE()), 112), 6)), 0) AS DECIMAL(18, 2))

我正在使用LEFT(CONVERT(varchar, DATEADD(month, -3, GETDATE(), 112), 6)),因为列名值将每月更新到当前月份。

我必须将 varchar 转换为十进制,因为我收到错误说不能对 varchar 值执行减法。

我哪里出错了,我的更新查询、更新表中每一行的 X 列和 Y 列值是否正确

tblSample [2006]-3565.24、[2005]-3461.36、[2004]-3510.36 列中的值。 输出

谢谢夏姆

【问题讨论】:

你能提供样本数据和想要的结果吗? 【参考方案1】:

您可以使用列名进行更新:

update tblsamples
    set x = [202006]-[202005],
        y = [202005]-[202004] ;

在表格中更改名称是一个真的坏主意。相反,您应该每月有一行。然后,您可以使用lag() 轻松计算差异:

select t.*, (value - lag(value) over (partition by ? order by yyyymm)) as diff
from t;

如有必要,可能会重新旋转。

如果您每个月都构建表格,那么您也应该构建差异。或者,也许更简单,只需添加名为 latest_monthprevious_month 的列并在 update 中使用这些列。

最后,如果您被这种格式卡住了,您将需要使用动态 SQL。不过,这似乎是个坏主意。

【讨论】:

我已经使用动态sql来构造tblSample。构建时,我无法在 tblSample 中添加 latest_month 和 previous_month。在上述共享查询中是否有将 varchar 转换为十进制的选项?

以上是关于列值是需要转换为十进制的varchar。列名采用日期格式。 sql服务器的主要内容,如果未能解决你的问题,请参考以下文章

将字典转换为数据框,键作为列名,键值作为数据框的列值

5月6日 MySQL

将varchar转换为十进制棒球平均值

SqlServer基本操作

根据列值动态获取列名

如何获得第二大列值和列名