如何更新 SET 语句以便我可以使用 MIN() 函数?

2 sql-server-2005 t-sql

我有一个现有的 UPDATE 表 SET 语句,该语句一直在工作,直到其中一个司机在他/她的班次中使用了两辆不同的卡车,所以现在我需要做的是修改 UPDATE 语句,以便我可以在几个卡车上使用 MIN() 函数列。当我尝试将 MIN() 函数添加到存在的语句中时,我收到了错误

聚合可能不会出现在 UPDATE 语句的集合列表中。”

这是我现有的 UPDATE 语句代码:

UPDATE #tmpDriverTime
SET @StartPlus8 =   CASE 
                        WHEN  ((CONVERT(int, DTE.StrtTm) + 800) > 2400) AND (CONVERT(INT, DTE.StartBreak) < 1600) THEN ((CONVERT(INT, DTE.StrtTm) + 800) - 2400)
                        ELSE (CONVERT(INT, DTE.StrtTm) + 800)
                    END,
    WorkDay1Break = CASE
                        WHEN ((WorkDay1 <=8) AND (WorkDay1Break = 0)) THEN 2 --Does not need a break
                        WHEN ((WorkDay1 > 8 AND DTE.StartBreak IS NULL) AND (WorkDay1Break = 0)) THEN 1 --Worked more then 8 hours with no break
                        WHEN (@StartPlus8 < CONVERT(INT, DTE.StartBreak) AND (WorkDay1Break = 0)) THEN 1 --Worked more then 8 hours before the first break
                        ELSE 0
                    END
FROM dbo.spr_DriverTimeEntry AS DTE
WHERE DTE.DrvrID = #tmpDriverTime.EmployeeNo
AND CONVERT(VARCHAR(12), DTE.dtwrkd, 112) = CONVERT(VARCHAR(12), @StartDate, 112)
AND DTE.PyrllID IN (
    1,
    222,
    1013,
    1014
);
Run Code Online (Sandbox Code Playgroud)

示例输入:

 Dtwrkd  Driver  StrTm  StartBreak
 1/1/11    1     0430   NULL 
 1/1/11    1     1200   1430
Run Code Online (Sandbox Code Playgroud)

目标结果:

 Dtwrkd  Driver  StrTm  StartBreak
 1/1/11    1     0430   1430
Run Code Online (Sandbox Code Playgroud)

我无法更改表架构,所以请不要进来告诉我我应该重新设计整个然后正确设置它,我没有那种奢侈。

我试过的代码产生了错误:

UPDATE #tmpDriverTime
SET @StartPlus8 =   CASE 
                        WHEN  ((CONVERT(int, MIN(DTE.StrtTm)) + 800) > 2400) AND (CONVERT(INT, DTE.MIN(StartBreak)) < 1600) THEN ((CONVERT(INT, MIN(DTE.StrtTm)) + 800) - 2400)
                        ELSE (CONVERT(INT, MIN(DTE.StrtTm)) + 800)
                    END,
    WorkDay1Break = CASE
                        WHEN ((WorkDay1 <=8) AND (WorkDay1Break = 0)) THEN 2 --Does not need a break
                        WHEN ((WorkDay1 > 8 AND MIN(DTE.StartBreak) IS NULL) AND (WorkDay1Break = 0)) THEN 1 --Worked more then 8 hours with no break
                        WHEN (@StartPlus8 < CONVERT(INT, MIN(DTE.StartBreak)) AND (WorkDay1Break = 0)) THEN 1 --Worked more then 8 hours before the first break
                        ELSE 0
                    END
FROM dbo.spr_DriverTimeEntry AS DTE
WHERE DTE.DrvrID = #tmpDriverTime.EmployeeNo
AND CONVERT(VARCHAR(12), DTE.dtwrkd, 112) = CONVERT(VARCHAR(12), @StartDate, 112)
AND DTE.PyrllID IN (
    1,
    222,
    1013,
    1014
);
Run Code Online (Sandbox Code Playgroud)

Aar*_*and 5

我不会试图理解或重写您的整个查询,但解决此解析器限制的典型形式是计算 CTE 中的聚合。基本思路:

;WITH cte(id, dt) AS 
(
  -- simplifying here, you'll need to with your logic
  SELECT DrvrID, MIN(datetimecolumn) 
  FROM dbo.spr_DriverTimeEntry
  -- WHERE ...
  GROUP BY DrvrID
)
UPDATE t
  SET t.StartPlus8 = cte.dt
  FROM #tmpDriverTime AS t
  INNER JOIN cte
  ON cte.id = t.EmployeeNo;
Run Code Online (Sandbox Code Playgroud)

为什么用不同的列名 ( EmployeeNo) 而不是它真正代表的 ( DrvrID)创建 #temp 表?

您是更新 #table 还是设置变量?选一个。

还要尽量避免将日期转换为字符串以查看它们是否在同一天 - 这是迄今为止效率最低的方法之一。