如何按X/Y/Z/P优先级筛选Question表数据?SQL技术咨询
分析你的SQL问题&正确实现优先级筛选
嘿,咱们先拆解下你的需求和现有SQL的问题,再给出靠谱的实现方案~
现有SQL的问题
你写的这段WHERE子句里的CASE表达式其实完全没实现优先级筛选的核心逻辑:
mclo.SubjectCode = (case when mclo.SubjectCode ='X' then 'X' else case when mclo.SubjectCode ='Y' then 'Y' else case when mclo.SubjectCode ='Z' then 'Z' else case when mclo.SubjectCode ='P' then 'P' end end end end)
这个逻辑等价于mclo.SubjectCode IN ('X','Y','Z','P')——不管SubjectCode是这四个里的哪一个,CASE都会返回它本身,所以只是过滤出了这四类记录,但根本没做到「优先选X,没有X再选Y」的核心要求,它会把所有符合这四个SubjectCode的记录都查出来,而不是按优先级取舍。
正确实现方案
根据你的需求(优先选X,无X则选Y,依此类推),分两种常见场景给出实现:
场景1:只返回最高优先级的所有记录
如果你的需求是只要该学生(StudentID=6588)下最高优先级的全部记录(比如有X的就全拿X的,没有X的就全拿Y的,以此类推),可以用窗口函数给记录按优先级打分,再筛选最高分:
WITH RankedQuestions AS ( SELECT dbo.GetStudentNumber('M', mcl.StudentID) AS Student_Number, mcl.SubjectCode, mcl.*, -- 按优先级赋值:X=1(最高), Y=2, Z=3, P=4 RANK() OVER (ORDER BY CASE mclo.SubjectCode WHEN 'X' THEN 1 WHEN 'Y' THEN 2 WHEN 'Z' THEN 3 WHEN 'P' THEN 4 ELSE 5 -- 其他SubjectCode优先级最低,会被排除 END ) AS PriorityRank FROM dbo.Question mcl INNER JOIN Answer mclo ON mclo.AnswerID = mcl.AnswereID WHERE mcl.StudentID = 6588 AND mclo.SubjectCode IN ('X', 'Y', 'Z', 'P') -- 仅保留指定优先级的SubjectCode ) SELECT Student_Number, SubjectCode, * -- 若不需要PriorityRank,可明确列出需要的列 FROM RankedQuestions WHERE PriorityRank = 1; -- 只取最高优先级的记录
这个逻辑的核心是:用RANK()给每个记录按SubjectCode的优先级排序,最高优先级的记录会得到PriorityRank=1,最后只筛选出这部分记录。如果存在X的记录,就只会返回X的;如果没有X,Y的就会成为最高优先级,以此类推。
场景2:返回所有符合的记录,但按优先级排序
如果你需要返回所有X/Y/Z/P的记录,但要求X排在最前面,然后是Y、Z、P,可以直接在ORDER BY里用CASE指定排序规则:
SELECT dbo.GetStudentNumber('M', mcl.StudentID) AS Student_Number, mcl.SubjectCode, mcl.* FROM dbo.Question mcl INNER JOIN Answer mclo ON mclo.AnswerID = mcl.AnswereID WHERE mcl.StudentID = 6588 AND mclo.SubjectCode IN ('X', 'Y', 'Z', 'P') ORDER BY CASE mclo.SubjectCode WHEN 'X' THEN 1 WHEN 'Y' THEN 2 WHEN 'Z' THEN 3 WHEN 'P' THEN 4 ELSE 5 END;
内容的提问来源于stack exchange,提问作者Akash Vishwakarma
相关产品推荐
相关产品推荐

