Sql server 如何在MSSQL中转换Top分析命令中的持续时间
我目前正在通过SAS运行一个小脚本,以使用Linux中Top的默认布局分析Top命令数据。数据当前正在传输到MSSQL数据库中。在您提问之前,SAS语言在处理空间变化方面做得很好,在“顶部”结果中,从一行到另一行可能非常具有挑战性 我需要做的是将“进程持续时间”列转换为可以执行聚合函数(例如平均值、最小值、最大值)的数据类型。默认情况下,该值显示为(粗体强调): 我对创建报告感兴趣,例如:Sql server 如何在MSSQL中转换Top分析命令中的持续时间,sql-server,Sql Server,我目前正在通过SAS运行一个小脚本,以使用Linux中Top的默认布局分析Top命令数据。数据当前正在传输到MSSQL数据库中。在您提问之前,SAS语言在处理空间变化方面做得很好,在“顶部”结果中,从一行到另一行可能非常具有挑战性 我需要做的是将“进程持续时间”列转换为可以执行聚合函数(例如平均值、最小值、最大值)的数据类型。默认情况下,该值显示为(粗体强调): 我对创建报告感兴趣,例如: Top 5 Users User Command #TimesRun AverageDurat
Top 5 Users
User Command #TimesRun AverageDuration (hh:mm:ss.x)
User A processX 2 00:00:10.5
...
我知道,一旦我可以将原始字符串转换为时间,我就可以使用DATEPART之类的帮助工具解析数学。但是,在原始VARCHAR列上使用CAST、CONVERT甚至ALTER都会抱怨“转换日期和/或时间格式字符串时转换失败”
该字段是系统中的VARCHAR(8)
任何想法都会非常有用。您面临的问题是无法直接更改列数据类型-其中的数据与时间不兼容,这意味着需要首先转换 您不能同时转换和更改列类型-这是不可能的-您存储的
VARCHAR(8)
作为time
没有直接意义,这就是更改列类型失败的原因(SQL Server不知道如何进行转换,并且在尝试更改列类型时无法指定规则)
您可以进行多步骤转换:
temp\u ProcTimeDur
),类型为TIME
替换为:
,确保ProcTimeDur
的格式与内置转换兼容UPDATE TopKPIInfo
SET temp_ProcTimeDur = CONVERT(Time, ProcTimeDur, 114)
ProcTimeDur
temp\u ProcTimeDur
重命名为ProcTimeDur
下面是之前发布的评论的一个廉价示例。我选择转换为基于分钟的值,因为这是您的原始数据。我做了一些假设——根据表的质量,这些假设可能有效,也可能无效。如果需要,您可以将此逻辑定义为视图,但前提是存储在时间列中的值格式一致且正确
with cte as (select * from (values ('00:00.04'), ('00:20.97'), ('01:59.00'), ('25:01.55')) as samp(tm)),
samples as (select tm, left(tm,2) as hh, SUBSTRING(tm,4, 2) as mm, right(tm,3) as sx from cte)
select *,
cast(hh as float) * 60 as hr_inmin, cast(mm as float) as mm_inmin, cast(sx as float) as ss_inmin,
(cast(hh as float) * 60) + cast(mm as float) + cast(sx as float) as usabletime_minutes
from samples
;
您可以使用DatetimefromParts获得以下信息:
select [user], [command], [TimesRun] = count(*), AverageDuration = avg(TimeDetails)
from (
select [TimeDetails] = convert(time, DATETIME2FROMPARTS(1900,1,1,
isnull(convert(int,PARSENAME(replace(timesrun, ':','.'),4)) ,0),
isnull(convert(int,PARSENAME(replace(timesrun, ':','.'),3)) ,0),
isnull(convert(int,PARSENAME(replace(timesrun, ':','.'),2)) ,0),
isnull(convert(int,PARSENAME(replace(timesrun, ':','.'),1)) ,0),
7)), * from #yourtime
) a
group by a.[user], a.[command]
DigiFriend,这是有道理的,但即使使用了正确类型的新列,我仍然会收到相同的错误。很遗憾,Update语句没有完成。请确保您使用了正确的转换函数-我从您的代码中复制了该函数,这可能不正确。请尝试
选择convert(Time,ProcTimeDur,114)从TopKPIInfo
但使用不同的强制转换/转换-直到您找到一个可以正常工作。114
不正确,因为它预期hh:mm:ss:mmm
,而不是hh:mm:ss.mmm
(注意最后一个分隔符-您的是一个
,114
需要一个:
。在转换之前,您可以通过将
替换为:
来解决这个问题。您的数据和到目前为止提出的建议会有一个巨大的问题。请仔细查看您的示例。“00:20.97”到底是什么?97是一分钟的-97/100?如果您不小心,时间数据类型在这里可能没有用处。时间域的上限小于24小时。这是一个问题吗?在开始做出假设之前,请先进行数据分析。
with cte as (select * from (values ('00:00.04'), ('00:20.97'), ('01:59.00'), ('25:01.55')) as samp(tm)),
samples as (select tm, left(tm,2) as hh, SUBSTRING(tm,4, 2) as mm, right(tm,3) as sx from cte)
select *,
cast(hh as float) * 60 as hr_inmin, cast(mm as float) as mm_inmin, cast(sx as float) as ss_inmin,
(cast(hh as float) * 60) + cast(mm as float) + cast(sx as float) as usabletime_minutes
from samples
;
select [user], [command], [TimesRun] = count(*), AverageDuration = avg(TimeDetails)
from (
select [TimeDetails] = convert(time, DATETIME2FROMPARTS(1900,1,1,
isnull(convert(int,PARSENAME(replace(timesrun, ':','.'),4)) ,0),
isnull(convert(int,PARSENAME(replace(timesrun, ':','.'),3)) ,0),
isnull(convert(int,PARSENAME(replace(timesrun, ':','.'),2)) ,0),
isnull(convert(int,PARSENAME(replace(timesrun, ':','.'),1)) ,0),
7)), * from #yourtime
) a
group by a.[user], a.[command]