TSQL中的Set statment中不允许使用聚合函数

时间:2016-08-30 13:25:16

标签: sql-server tsql

我需要使用另一个表(msdb.dbo.sysjobhistory)中的值更新一个表。因为我需要获取run_time和run_date的最大值,所以我一直得到'set statement'中不允许的聚合函数'错误。作为一种解决方法,我尝试了以下但是有些事情是不对的,因为每一行中的所有值都是相同的,表明连接中的错误或者我无法弄清楚的东西。这就是我所拥有的(这不是正确的):

UPDATE inventory.dbo.books SET 
   auth_time = t1.at,
   auth_date = t1.ad
FROM (SELECT MAX(run_time) AS at, MAX(run_date) AS ad
      FROM  msdb.dbo.sysjobhistory h 
       INNER JOIN inventory.dbo.books t 
          ON h.job_id = t.jobid) t1

另外,我需要能够将run_time转换为十进制(10,2)格式(因为auth_time字段是这样),run_date转换为datetime(因为auth_time是日期时间格式)。

2 个答案:

答案 0 :(得分:1)

你真是太近了!

只需将子查询引用从From子句移动到Set for each字段中的子查询。

试试这个:

UPDATE inventory.dbo.books SET 
   auth_time = (SELECT MAX(run_time) 
                FROM msdb.dbo.sysjobhistory h 
                    INNER JOIN inventory.dbo.books t 
                        ON h.job_id = t.jobid)
   , auth_date = (SELECT MAX(run_date) 
                    FROM msdb.dbo.sysjobhistory h 
                        INNER JOIN inventory.dbo.books t 
                            ON h.job_id = t.jobid);

每个字段的SET中的子查询实际上在执行子查询时返回单个值。因此,使用子查询不会破坏任何设置操作的规则。

如果您的逻辑开始变得太复杂并且您的设置字段太多而无法重复所有内容作为每个字段的子查询,那么您也可以使用CTE。

With CTE as (
Select MAX(run_time) as at
    , MAX(run_date) as ad 

FROM msdb.dbo.sysjobhistory h 
    INNER JOIN inventory.dbo.books t 
        ON h.job_id = t.jobid
) 

Update #Temp
Set auth_time = CTE.at
    , auth_date = CTE.ad

From CTE

如果您有任何疑问,请与我联系!

答案 1 :(得分:1)

您可以加入子查询 在那个子查询中,你被允许使用group by 然后在设置目标字段时进行转换或转换。

例如:

UPDATE b
SET 
 auth_time = left(replace(cast(h.max_run_time as varchar),':',''),8),
 auth_date = cast(h.max_run_date as datetime)
FROM inventory.dbo.books b
JOIN (
    select 
    job_id, 
    max(run_time) as max_run_time, 
    max(run_date) as max_run_date
    from msdb.dbo.sysjobhistory 
    group by job_id
) h 
ON (b.job_id = h.job_id);

我不知道该auth_time期望的是什么类型的号码 所以max_run_time只是从TIME转换为VARCHAR varchar隐式转换为目标字段的DECIMAL。

例如:time' 12:15:25.0000000' - >十进制(10,2)121525.00