【问题标题】:Update data based on other column根据其他列更新数据
【发布时间】:2014-06-13 11:42:44
【问题描述】:

我有一张表,想根据同一张表的其他列更新一列。表格设计和表格数据请看下图。

在这个 tbl 中,我想按以下步骤更新 JoinDate。

1) 如果 ModifiedDatetime 不为 null,则 ModifiedDatetime 否则 CreatedDate。

2) 现在如果 NextLevel 是 Hour 那么想要添加我们在 setp 1 中拥有的上述日期的小时

3) 现在如果 NextLevel 是 Day 那么想要添加我们在 setp 1 中拥有的上述日期的 Day

4) 现在如果 NextLevel 是 Min 然后想要添加我们在 setp 1 中拥有的上述日期的 Min

5) 最后在完成所有上述过程后,我将获得日期,我想使用该数据来更新 joindate。

我在光标下方执行了此操作,但我想使用 sql 更新查询来执行此操作。

DECLARE @EmpID INT
Declare @DtTm datetime
DECLARE @NextLevl INT
Declare @JoinDtTm datetime

DECLARE CurProg CURSOR FOR 
select EmpID from tblEmp 

OPEN CurProg
FETCH NEXT
FROM CurProg INTO @EmpID
WHILE @@FETCH_STATUS = 0
BEGIN
select @DtTm = case when ModifiedTime is null then CreatedDate else ModifiedTime end, @NextLevl = NextLevel  from tblEmp where EmpID = @EmpID
if (@NextLevl = 'Min')
BEGIN
   set @JoinDtTm = DATEADD(MI,1,@DtTm)
END
ELSE IF (@NextLevl= 'Hour')
BEGIN
   set @JoinDtTm = DATEADD(HH,1,@DtTm)
END
ELSE
BEGIN
   set @JoinDtTm = DATEADD(D,1,@DtTm)
END
--update tblEmp set JoinDtTm = @JoinDtTm where EMPId= @EMPId


FETCH NEXT
FROM CurProg INTO @EmpID
END
CLOSE CurProg
DEALLOCATE CurProg

谢谢, 希特什

【问题讨论】:

  • 所以这是你的要求。你有没有尝试过?
  • 是的,我使用 CURSOR 完成了此操作,但我想在没有光标的情况下完成此操作。
  • 使用光标发布您的代码...如果不出意外,它将有助于澄清您的问题。
  • 您好,我已经编辑了我的问题,并在其中添加了我的 CURSOR。

标签: sql sql-server sql-server-2008 sql-update


【解决方案1】:

试试这个:

UPDATE TableName
SET JoinDate = CASE WHEN NextLevel = 'Hour' THEN DATEADD(HH,1,ISNULL(ModifiedDate,CreatedDate))
                    WHEN NextLevel = 'Day' THEN DATEADD(DD,1,ISNULL(ModifiedDate,CreatedDate))
                    WHEN NextLevel = 'Min' THEN DATEADD(MI,1,ISNULL(ModifiedDate,CreatedDate))
                END

【讨论】:

  • 你将如何处理未来的插入?每天、每小时、每 10 分钟运行一次更新。也许使用触发器?虽然这回答了问题,但这不是一个好方法。
  • @t-clausen.dk 用于将来的插入,在 WHERE 子句中我们可以有条件 UPDATE ... ... WHERE JoinDate IS NULL。
  • @NithinGangadharan 所以每次插入时,您也会进行更新。你不觉得有问题吗?如果需要,您的列应该被计算可能也被保留
  • @t-clausen.dk 如果您看一下要求,那张海报中提到要首先考虑 ModifiedDate。这意味着在插入值后可能会执行很少的操作。 COMPUTED 列可能没有用,因为 JoinDate 只计算一次,每次执行查询时计算这个值都会产生不必要的开销。而且也不能使用 PERSISTED,因为正如我提到的,JoinDate 可能会在执行几个步骤后计算,因此 ModifiedDate 会更新,并且一旦插入值,PERSISTED 字段就会生成并存储值。
【解决方案2】:

要在更新语句中不使用游标来执行此操作,那么这应该可以工作

    UPDATE TBL_EMP
SET JOINDATE =
(CASE WHEN MODIFIEDTIME IS NOT NULL 
THEN (CASE WHEN NEXTLEVEL ='Hour' THEN dateadd(hh,1,modifiedtime) 
ELSE (CASE WHEN NEXTLEVEL = 'Day'  THEN dateadd(dd,1,MODIFIEDTIME)  
ELSE(CASE WHEN NEXTLEVEL = 'Min'  THEN dateadd(n,1,MODIFIEDTIME)  ELSE MODIFIEDTIME END) END) END)
ELSE(CASE WHEN NEXTLEVEL ='Hour' THEN dateadd(hh,1,CREATEDDATE)  
ELSE(CASE WHEN NEXTLEVEL = 'Day' THEN dateadd(dd,1,CREATEDDATE) 
ELSE(CASE WHEN NEXTLEVEL = 'Min'   THEN dateadd(n,1,CREATEDDATE)  ELSE CREATEDDATE END) END) END) END)
FROM TBL_EMP

【讨论】:

    【解决方案3】:

    删除您的列连接日期,这是多余的。由于 joindate 总是依赖于同一行中的其他列,因此您只需要一个这样的计算列,否则您将被困在不断维护 joindate 中的值:

    ALTER TABLE YourTable
    ADD cJoindate as
      CASE NextLevel 
        WHEN 'day' THEN DATEADD(D, 1, COALESCE(ModifiedDate,CreatedDate))
        WHEN 'min' THEN DATEADD(MI, 1, COALESCE(ModifiedDate,CreatedDate))
        WHEN 'hour' THEN DATEADD(HH, 1, COALESCE(ModifiedDate,CreatedDate))
      END
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多