我在构建简洁的更新语句时遇到了麻烦。这是示例数据库的小提琴:http://sqlfiddle.com/#!6/6899b0
它包含具有多个地址的客户表。
现在我需要使用以下逻辑转换ABadrestype = '-1'
中的[AdresBewoners]
条目:
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
这可以在一个更新声明中完成吗?
编辑:这是等效的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
问题仍然相同:可以在一个UPDATE语句中完成吗?
答案 0 :(得分:1)
如果要插入所需的记录,请避免在表格上进行更新
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])
AND 如果您想强制更新命令而不是表,那可能就像
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
答案 1 :(得分:0)
您可以通过以下查询进行更新。您可以将连接与其他表和更复杂的case子句一起使用。我不了解你的最后一个要求,所以你需要稍微升级一下。
update A
set A.ABadrestype =
(CASE WHEN A.ABadrestype = 1 THEN 2 ELSE -1 END)
from Adresbewoners A
where A.ABtypebewoner = 'K'