当逻辑为-SQL Server时,使用单个大小写更新多个列
我需要使用硬代码数据创建一个带有自定义元素和属性的XML 表架构:StudentMark: 样本种子数据当逻辑为-SQL Server时,使用单个大小写更新多个列,sql,sql-server,sql-update,sql-server-2016,case-when,Sql,Sql Server,Sql Update,Sql Server 2016,Case When,我需要使用硬代码数据创建一个带有自定义元素和属性的XML 表架构:StudentMark: 样本种子数据 INSERT INTO [dbo].[StudentMark] ([StudentId], [SubjectId], [GeneratedOn], [Score]) VALUES ('FC3CB475-B480-4129-9190-6DE880E2D581', '0D72F79E-FB48-4D3E-9906-B78A9D105081', '2017-08-10 10:10:15', 95)
INSERT INTO [dbo].[StudentMark] ([StudentId], [SubjectId], [GeneratedOn], [Score])
VALUES ('FC3CB475-B480-4129-9190-6DE880E2D581', '0D72F79E-FB48-4D3E-9906-B78A9D105081', '2017-08-10 10:10:15', 95),
('0F4EF48C-93E3-41AA-8295-F6B0E8D8C3A2', '0D72F79E-FB48-4D3E-9906-B78A9D105081', '2017-08-10 10:10:15', 60),
('0F4EF48C-93E3-41AA-8295-F6B0E8D8C3A2', 'AB172272-D2E9-49E1-8040-6117BB6743DB', '2017-08-16 09:06:20', 25),
('FC3CB475-B480-4129-9190-6DE880E2D581', 'AB172272-D2E9-49E1-8040-6117BB6743DB', '2017-08-16 09:06:20', 45);
要求:我需要基于单个逻辑更新列[IsPass]和[Result]的耦合
问题1:
如何将这两个查询合并到一个更新查询中,而不使用
复制案例时
请帮助我
UPDATE SM
SET SM.[Result] = CASE WHEN SM.[Score] >= 75 THEN N'OUTSTANDING'
WHEN SM.[Score] >= 60 AND [Score] < 75 THEN N'VERY GOOD'
WHEN SM.[Score] >= 50 AND [Score] < 60 THEN N'GOOD'
WHEN SM.[Score] >= 40 AND [Score] < 50 THEN N'AVERAGE'
ELSE N'FAIL' END, SM.[IsPass] = CASE WHEN SM.[Score] < 40 THEN 0 ELSE 1 END
FROM [dbo].[StudentMark] SM
通过添加逗号,您可以很容易地做到这一点,例如:
WITH DataSource ([StudentMarkId], [Result]) AS
(
SELECT [StudentMarkId]
,CASE WHEN SM.[Score] >= 75 THEN N'OUTSTANDING'
WHEN SM.[Score] >= 60 AND [Score] < 75 THEN N'VERY GOOD'
WHEN SM.[Score] >= 50 AND [Score] < 60 THEN N'GOOD'
WHEN SM.[Score] >= 40 AND [Score] < 50 THEN N'AVERAGE'
ELSE N'FAIL' END
FROM [dbo].[StudentMark]
)
UPDATE [dbo].[StudentMark]
SET SM.[Result] = DS.[Result]
,SM.[IsPass] = CASE WHEN DS.[Result] = N'FAIL' THEN 0 ELSE 1 END
FROM [dbo].[StudentMark] SM
INNER JOIN DataSource DS
ON SM.[StudentMarkId] = DS.[StudentMarkId];
您可以简单地重复以下逻辑:
UPDATE SM
SET SM.[Result] = (CASE WHEN SM.[Score] >= 75 THEN N'OUTSTANDING'
WHEN SM.[Score] >= 60 THEN N'VERY GOOD'
WHEN SM.[Score] >= 50 THEN N'GOOD'
WHEN SM.[Score] >= 40 THEN N'AVERAGE'
ELSE N'FAIL'
END),
SM.IsPass = (CASE WHEN SM.Score >= 40 THEN 1 ELSE 0 END)
FROM [dbo].[StudentMark] SM;
注意:CASE表达式保证按顺序求值,因此每行只需进行一次比较
不过,我要指出的是,一个更好的选择可能是在表中取消IsPass作为列,并将其作为计算列:
alter table [dbo].[StudentMark]
add IsPass as (CASE WHEN Result <> N'FAIL' THEN 1 ELSE 0 END);
这可确保值始终正确。事实上,您可以对结果执行相同的操作,因此两者都是计算出来的。我已经尝试过这种逻辑,但它总是将[IsPass]更新为1。这就是我发布这个问题的原因。哦!!,最初,您在一个查询中尝试两个事务。您需要使用两个查询。或者你可以像我在编辑的答案中那样稍微改变一下逻辑。通常将相同的信息存储多次分数、分数作为文本、通过/失败是一个坏主意,因为如果你更新数据,可能会在那一点上遗漏一些内容,然后数据会出现不匹配。在应用层、视图、计算列的其他地方使用score+逻辑可能值得考虑
WITH DataSource ([StudentMarkId], [Result]) AS
(
SELECT [StudentMarkId]
,CASE WHEN SM.[Score] >= 75 THEN N'OUTSTANDING'
WHEN SM.[Score] >= 60 AND [Score] < 75 THEN N'VERY GOOD'
WHEN SM.[Score] >= 50 AND [Score] < 60 THEN N'GOOD'
WHEN SM.[Score] >= 40 AND [Score] < 50 THEN N'AVERAGE'
ELSE N'FAIL' END
FROM [dbo].[StudentMark]
)
UPDATE [dbo].[StudentMark]
SET SM.[Result] = DS.[Result]
,SM.[IsPass] = CASE WHEN DS.[Result] = N'FAIL' THEN 0 ELSE 1 END
FROM [dbo].[StudentMark] SM
INNER JOIN DataSource DS
ON SM.[StudentMarkId] = DS.[StudentMarkId];
UPDATE SM
SET SM.[Result] = (CASE WHEN SM.[Score] >= 75 THEN N'OUTSTANDING'
WHEN SM.[Score] >= 60 THEN N'VERY GOOD'
WHEN SM.[Score] >= 50 THEN N'GOOD'
WHEN SM.[Score] >= 40 THEN N'AVERAGE'
ELSE N'FAIL'
END),
SM.IsPass = (CASE WHEN SM.Score >= 40 THEN 1 ELSE 0 END)
FROM [dbo].[StudentMark] SM;
alter table [dbo].[StudentMark]
add IsPass as (CASE WHEN Result <> N'FAIL' THEN 1 ELSE 0 END);