MSSQL:当单元格为空时,用动态变量数据更新一行

时间:2014-10-06 18:28:20

标签: sql-server if-statement sql-update

我需要使用与约束匹配的最后一个有效行中的数据更新一行为空的前三列(此约束在此情况下是常量,它是特定的进程名称)。前三列中具有空数据的连续行数不是常量。

我正在考虑使用这种逻辑,我只是​​不确定如何在MSSQL中编写它

伪代码:

declare @tmp_pname nvarchar(50);
declare @tmp_datetime datetime;
declare @tmp_pid int;
if ProcessName == "MyProc"
    set @tmp_pname = ProcessName
    set @tmp_datetime = DateTime
    set @tmp_pid = PID
else if ProcessName == ""
    update table 
        set ProcessName = @tmp_pname
        set DateTime = @tmp_datetime
        set PID = @tmp_pid

示例数据:

Id    ProcessName     DateTime     PID     LineData
1     Myproc          tmpstamp     123     uniqueData
2     ''              ''           ''      uniqueData
3     ''              ''           ''      uniqueData
4     myproc          tmpstamp     444     uniqueData
5     ''              ''           ''      uniqueData

预期结果:

row 2 and 3 get their processname, datetime, and pid from row 1
row 5 gets its processname, datetime, and pid from row 4

先谢谢您的帮助!

1 个答案:

答案 0 :(得分:2)

<强> SQL2012 +

您可以扩展下一个解决方案:

DECLARE @MyTable TABLE (
    Id          INT PRIMARY KEY,
    ProcessName VARCHAR(10) NOT NULL
);
INSERT  @MyTable (Id, ProcessName) VALUES (1, 'Myproc')
INSERT  @MyTable (Id, ProcessName) VALUES (2, '')
INSERT  @MyTable (Id, ProcessName) VALUES (3, '')
INSERT  @MyTable (Id, ProcessName) VALUES (4, 'myproc')
INSERT  @MyTable (Id, ProcessName) VALUES (5, '')
INSERT  @MyTable (Id, ProcessName) VALUES (6, 'SProc')
INSERT  @MyTable (Id, ProcessName) VALUES (8, '');

WITH Base
AS (
    SELECT  y.ProcessName, y.HasValue, SUM(y.HasValue) OVER(ORDER BY y.Id) AS GroupId
    FROM (
        SELECT  x.Id, x.ProcessName, CASE WHEN x.ProcessName = '' THEN 0 ELSE 1 END AS HasValue
        FROM    @MyTable x 
    ) y 
)
UPDATE  [target]
SET     ProcessName = source.ProcessName
FROM    Base [target] INNER JOIN Base source ON [target].GroupId = source.GroupId   
WHERE   [target].HasValue = 0
AND     source.HasValue = 1;

SELECT  *
FROM    @MyTable

注意#1:我假设Id值是唯一且必须的。

注意#2:我认为ProcessName列是强制性的(NOT NULL)。

注意#3:(...) y派生表将源数据集(@MyTable)拆分为GroupId标识的子组,从而(1)来自{的每个非空字符串值{1}}列开始新的ProcessName和(2)计算GroupId值,它使用GroupId列中值的升序。

示例:

Id