Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何在MSSQL中转换Top分析命令中的持续时间_Sql Server - Fatal编程技术网

Sql server 如何在MSSQL中转换Top分析命令中的持续时间

Sql server 如何在MSSQL中转换Top分析命令中的持续时间,sql-server,Sql Server,我目前正在通过SAS运行一个小脚本,以使用Linux中Top的默认布局分析Top命令数据。数据当前正在传输到MSSQL数据库中。在您提问之前,SAS语言在处理空间变化方面做得很好,在“顶部”结果中,从一行到另一行可能非常具有挑战性 我需要做的是将“进程持续时间”列转换为可以执行聚合函数(例如平均值、最小值、最大值)的数据类型。默认情况下,该值显示为(粗体强调): 我对创建报告感兴趣,例如: Top 5 Users User Command #TimesRun AverageDurat

我目前正在通过SAS运行一个小脚本,以使用Linux中Top的默认布局分析Top命令数据。数据当前正在传输到MSSQL数据库中。在您提问之前,SAS语言在处理空间变化方面做得很好,在“顶部”结果中,从一行到另一行可能非常具有挑战性

我需要做的是将“进程持续时间”列转换为可以执行聚合函数(例如平均值、最小值、最大值)的数据类型。默认情况下,该值显示为(粗体强调):

我对创建报告感兴趣,例如:

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]