如何根据条件更新某些行?

问题描述 投票:0回答:1

我正在努力实施两个“标志”列,以显示申请人是否已经经历了称为“清算”的流程,以及该申请人是否事先向大学提出了标准申请,然后进行了清算。这两个标志被称为“In Clearing?”和“之前的标准申请?”

我可以根据两个表中的两列来判断申请人是否已通过 Clearing:“Decision Desc”=“UA Clearing”(表“Sequence”),以及他们的“Choice Number”= 7(表“Final”)。如果这些条件成立,他们会在“在空地中?”中回答“是”。专栏。

我可以判断清算申请人是否也有先前的标准申请,因为他们将在现有的“UA Clearing”和“选择编号”= 7 的另一行之上还有另一行“选择编号”= 1-5。如果这些条件成立,他们会在“先前的标准申请?”中选择“是”。专栏。

每个申请人/行都有唯一的标识符“ID”。唯一应受此流程影响的申请人是“选择编号”7 的申请人。

总结一下: “在空地?”如果决策描述 = 'UA Clearing' 且 '选择编号' = 7,则 = '是'。 “之前的标准应用?”如果“正在清算”=“是”且“选择编号”= 1-5,则 =“是”。 仅向“选择编号”= 7 的行添加“是”。

我无法解决的问题:使唯一受此影响的行是“选择编号”7 的行。

例如,这就是我的目标:

身份证 课程代码 决策描述 选择号码 在清理中? 之前的标准申请?
U15 A1 UA清算 1
U15 C7 UA清算 7 是的 是的
U48 R9 UA清算 2
U53 G1 UA清算 7 是的

如您所见,U15 的两行均为“是”,因为它有一行“决策描述”=“UA 清算”且“选择编号”= 7,另一行的选择编号为“1-5”。然而,“在空地里?”和“先前的标准应用?”只能在选项号为“7”的行上显示“是”。

这是我尝试过的代码:

DROP TABLE IF EXISTS SA_ConfirmationAndClearing_CurrentYearDecisionSequence_Clearing;

-- Copy data of BOXI source into new file for Clearing content
SELECT *
INTO SA_ConfirmationAndClearing_CurrentYearDecisionSequence_Clearing
FROM SA_ConfirmationAndClearing_CurrentYearDecisionSequence

-- Add Flag columns to Sequence_Clearing show whether an applicant is in Clearing or not, and if they have a standard application prior to clearing.
-- Done repeatedly because this table is dropped in this script
ALTER TABLE SA_ConfirmationAndClearing_CurrentYearDecisionSequence_Clearing 
ADD [In Clearing?] varchar(255),
    [Prior standard application?] varchar (255)

-- Create temporary table to track UCAS IDs with different application scenarios
DROP TABLE IF EXISTS #UCAS_ID_to_Choice_Number;

-- Classify UCAS IDs based on their choice numbers and decision desc
SELECT 
    Final.[UCAS Id],
    CASE
        WHEN COUNT(DISTINCT CASE WHEN Final.[Choice Number] = '7' THEN 1 ELSE NULL END) > 0
             AND COUNT(DISTINCT CASE WHEN Final.[Choice Number] IN ('1', '2', '3', '4', '5') THEN 1 ELSE NULL END) > 0 THEN '1-5 and 7 - Both'
        WHEN COUNT(DISTINCT CASE WHEN Final.[Choice Number] = '7' THEN 1 ELSE NULL END) > 0 THEN 'Only 7 - Clearing'
        ELSE '1-5 - Nulls'
    END as [Choice Number Type]
INTO #UCAS_ID_to_Choice_Number
FROM [REP_ConfirmationAndClearing_Final] as Final
JOIN SA_ConfirmationAndClearing_CurrentYearDecisionSequence_Clearing as Sequence
    ON Final.[UCAS Id] = Sequence.[UCAS Id]
WHERE Sequence.[Decision Desc] = 'UA Clearing'
GROUP BY Final.[UCAS Id];

-- Update the _Clearing table based on the temp table
UPDATE Sequence
SET
    [In Clearing?] = CASE
                        WHEN UCASTempTable.[Choice Number Type] IN ('Only 7 - Clearing', '1-5 and 7 - Both') THEN 'Yes'
                        ELSE NULL
                     END,
    [Prior standard application?] = CASE
                                        WHEN UCASTempTable.[Choice Number Type] = '1-5 and 7 - Both' THEN 'Yes'
                                        ELSE NULL
                                     END
FROM SA_ConfirmationAndClearing_CurrentYearDecisionSequence_Clearing as Sequence
JOIN #UCAS_ID_to_Choice_Number as UCASTempTable
    ON Sequence.[UCAS Id] = UCASTempTable.[UCAS Id]
WHERE Sequence.[Decision Desc] = 'UA Clearing';

-- Update the Final table
UPDATE Final
SET 
    Final.[In Clearing?] = COALESCE(Clearing.[In Clearing?], NULL),
    Final.[Prior standard application?] = COALESCE(Clearing.[Prior standard application?], NULL)
FROM [REP_ConfirmationAndClearing_Final] AS Final
INNER JOIN [SA_ConfirmationAndClearing_CurrentYearDecisionSequence_Clearing] AS Clearing
ON Final.[UCAS Id] = Clearing.[UCAS Id]
WHERE Clearing.[Decision Desc] = 'UA Clearing';

此脚本错误地将“是”添加到“选择编号”= 1-5 的行,而实际上应该是“选择编号”= 7 的行。

错误示例:

身份证 课程代码 决策描述 选择号码 在清理中? 之前的标准申请?
U15 A1 UA清算 1 是的 是的
U15 C7 UA清算 7 是的 是的

这里的错误是两行的“正在清除?”中都有“是”和“先前的标准应用?”列,而它只能是带有“选择编号”7 的列。

sql sql-server join set flags
1个回答
0
投票

我认为你所拥有的方式比需要的更复杂,并且可以简化为单个

SELECT
语句。

据我了解您的要求:

    仅对于具有
  1. [In Clearing?]
     的行,应将 
    'Yes'
    设置为
    [Choice Number] = '7'
  2. 如果具有相同 ID 的任何其他行具有
  3. [Prior standard application?]
    ,但您希望将其限制为具有 
    'Yes'
     的行,则 
    [Choice Number] IN ('1', '2', '3', '4', '5')
    应设置为
    [Choice Number] = '7'

第一个可以用简单的

CASE
表达式计算,因为条件只涉及同一行上的数据。

第二个可以使用

CASE
表达式、窗口函数和称为条件聚合的技术的组合来完成。

COUNT(...) OVER(...)
窗口函数允许我们从结果中的其他行中采样数据。
OVER(PARTITION BY ID)
将范围限制为具有相同
ID
值的行。不需要
GROUP BY
。通过在
CASE
内放置
COUNT(...)
表达式,我们可以将计数限制为满足条件的行。
THEN 1
案例被计算在内,而
 
ELSE NULL 案例则不被计算在内。这通常称为“条件聚合”。非零计数表示分区中的某些行满足条件。

由于您只想在具有

[Prior standard application?]

 的行上设置 
[Choice Number] = '7'
,因此我们只需添加 和 
AND
 条件即可达到此效果。

SELECT *, CASE WHEN [Choice Number] = '7' THEN 'Yes' END AS [In Clearing?], CASE WHEN [Choice Number] = '7' AND COUNT(CASE WHEN [Choice Number] IN ('1', '2', '3', '4', '5') THEN 1 END) OVER(PARTITION BY ID) > 0 THEN 'Yes' END AS [Prior standard application?] FROM SA_ConfirmationAndClearing_CurrentYearDecisionSequence WHERE [Decision Desc] = 'UA Clearing';
结果示例:

身份证课程代码决策描述选择号码在清理中?之前的标准申请?U15A1UA清算1空U15C7UA清算7是的是的U48R9UA清算2空U53G1UA清算7是的
请参阅

this db<>fiddle 进行演示。

© www.soinside.com 2019 - 2024. All rights reserved.