我正在努力实施两个“标志”列,以显示申请人是否已经经历了称为“清算”的流程,以及该申请人是否事先向大学提出了标准申请,然后进行了清算。这两个标志被称为“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 的列。
我认为你所拥有的方式比需要的更复杂,并且可以简化为单个
SELECT
语句。
据我了解您的要求:
[In Clearing?]
的行,应将
'Yes'
设置为 [Choice Number] = '7'
。[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';
结果示例:
空 | |||||
空 | |||||
空 |
this db<>fiddle 进行演示。