Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当逻辑为-SQL Server时,使用单个大小写更新多个列_Sql_Sql Server_Sql Update_Sql Server 2016_Case When - Fatal编程技术网

当逻辑为-SQL Server时,使用单个大小写更新多个列

当逻辑为-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)

我需要使用硬代码数据创建一个带有自定义元素和属性的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),
       ('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);