Sql 将时间缩短为一次更新?

Sql 将时间缩短为一次更新?,sql,sql-server,Sql,Sql Server,我在构造简洁的更新语句时遇到问题。下面是对示例数据库的修改: 它包含具有多个地址的客户表 现在我需要使用以下逻辑转换[AdresBewoners]中的ABadrestype='-1'项: 仅当ABtypebewoner='K'时转换 如果客户已经有一个主体地址ABadrestype='1',则将其更新为'2'。 否则,将第一个转换为“1”,如果有多个,则将任何其他转换为“2” 下面是在示例db seed语句旁边注释的预期结果,以清楚地看到需要更新的内容: [dbo].[AdresBewoners

我在构造简洁的更新语句时遇到问题。下面是对示例数据库的修改:

它包含具有多个地址的客户表

现在我需要使用以下逻辑转换[AdresBewoners]中的ABadrestype='-1'项:

仅当ABtypebewoner='K'时转换 如果客户已经有一个主体地址ABadrestype='1',则将其更新为'2'。 否则,将第一个转换为“1”,如果有多个,则将任何其他转换为“2” 下面是在示例db seed语句旁边注释的预期结果,以清楚地看到需要更新的内容:

[dbo].[AdresBewoners] VALUES
    (1, 1, 1, 'K', '1'),
    (2, 2, 1, 'K', '2'),
    (3, 3, 2, 'K', '2'),
    (4, 4, 2, 'K', '-1'), -- change to 1, as it's the first for a customer without a principal address
    (5, 5, 2, 'K', '-1'), -- change to 2, as it's the second for a customer without a principal address
    (6, 6, 1, 'K', '-1'), -- change to 2, as the customer already has a principal address
    (7, 7, 3, 'Z', '1'),
    (8, 8, 3, 'Z', '-1')  -- leave as is; "Z" denotes other entity type
这可以在单个update语句中完成吗

编辑:这是WHILE等效项:

-- Fetch affected records.
INSERT INTO
    #tmp_adresbewoners
SELECT
    ABid,
    ABidB
FROM
    AdresBewoners
WHERE
    ABtypebewoner = 'K'
    AND ABadrestype = '-1'

-- Declare cursor
DECLARE @cursor CURSOR
DECLARE @ABid int
DECLARE @ABidB int

SET @cursor = CURSOR FOR
    SELECT
        ABid,
        ABidB
    FROM
        #tmp_adresbewoners

OPEN @cursor
FETCH NEXT FROM @cursor INTO @ABid, @ABidB

WHILE @@FETCH_STATUS = 0
BEGIN

    UPDATE
        AdresBewoners
    SET
        -- If no principal address exists for the current customer, use '1', else use '2'
        ABadrestype = CASE
            WHEN NOT EXISTS (SELECT ABid FROM Adresbewoners WHERE ABidB = @ABidB AND ABtypebewoner = 'K' AND ABadrestype = '1') THEN '1'
            ELSE '2'
        END
    WHERE
        ABid = @ABid

    FETCH NEXT FROM @cursor INTO @ABid, @ABidB

END

CLOSE @cursor

问题是一样的:这可以在一个更新语句中完成吗?

您可以通过下面的查询来更新它。您可以将联接用于其他表和更复杂的case子句。我不明白你的上一个要求,所以你需要升级一点

update A
set A.ABadrestype = 
(CASE WHEN A.ABadrestype = 1 THEN 2 ELSE -1 END)
from Adresbewoners A
where A.ABtypebewoner = 'K'

如果希望插入所需的记录并避免对表进行更新

INSERT INTO [dbo].[AdresBewoners] 
select [ABid], [ABidA], [ABidB], [ABtypebewoner],
       coalesce(case when (ABtypebewoner = 'K' and [ABadrestype] = -1) then null else [ABadrestype] end, 
               case when lag(ABadrestype) over (order by ABid) <> [ABadrestype] then 1 else 2 end) [ABadrestype]
from
(
    VALUES
    (1, 1, 1, 'K', '1'),
    (2, 2, 1, 'K', '2'),
    (3, 3, 2, 'K', '2'),
    (4, 4, 2, 'K', '-1'), -- change to 1, as it's the first for a customer without a principal address
    (5, 5, 2, 'K', '-1'), -- change to 2, as it's the second for a customer without a principal address
    (6, 6, 1, 'K', '-1'), -- change to 2, as the customer already has a principal address
    (7, 7, 3, 'Z', '1'),
    (8, 8, 3, 'Z', '-1')  -- lea
)a([ABid], [ABidA],[ABidB], [ABtypebewoner], [ABadrestype]) 
若您想在表上强制执行update命令,那个么可能是这样的

update a set a.ABadrestype = aa.[ABadrestype] from AdresBewoners a
join (
    select [ABid], [ABidA], [ABidB], [ABtypebewoner],  
       coalesce(case when (ABtypebewoner = 'K' and [ABadrestype] = -1) then null else [ABadrestype] end, 
               case when lag(ABadrestype) over (order by ABid) <> [ABadrestype] then 1 else 2 end) [ABadrestype]  from AdresBewoners
) aa on aa.ABid = a.ABid

你首先如何定义?这是最低阿比德的记录吗?也许你可以包括什么?还有,所有的模式都与问题有关吗?@destination data是的,最低的ABid是可以的。@KtX2SkD我想,但我没有设法在一些表连接的情况下进行常规更新。。。条件部分让我困惑。这没有考虑到预先存在的地址。我需要update语句。记录已存在于数据库中。当运行您提供的update语句时,我得到以下信息:窗口函数只能出现在SELECT或ORDER BY子句中。但有一个问题:LAG固有地意味着主体地址ABADRESYPE=1在按ID排序时应该是第一个地址。但情况并非总是如此。。。