首页 > 解决方案 > 如何在sql的case块中嵌套逻辑

问题描述

我有一张包含学生考试成绩的表格。每种测试类型可以有超过 1 个分数。所以学生 A 可以有多个测试 1 的分数,一个测试 2 的分数,等等。

基本上,如果一个学生只有测试 1 的测试成绩,我想做 x。如果一个学生有多个测试 1 的测试分数,我想做 y。我怎样才能做到这一点?

到目前为止,我的查询是:

SELECT A.*
  ,T.TestType
  ,CASE
    WHEN T.TestType = 'test_1' THEN T.MessageLocation
  END AS Loc
FROM #Person A
LEFT JOIN #TestScores T ON A.TestID = T.ID

但我想做的(伪代码)是:

SELECT A.*
  ,T.TestType
  ,CASE
    -- when count(test_1) = 1 THEN T.MessageLocation
    -- when count(test_1) > 1 THEN
    -- for each row T.AltMessageLocation
  END AS Loc
FROM #Person A
LEFT JOIN #TestScores T ON A.TestID = T.ID

标签: sqlselectsubquery

解决方案


您需要先按 ResrID 和 TestType 聚合数据,然后将结果加入现有查询。假设您使用的是 SQL Server,它将类似于:

;WITH cteTestNum(
  SELECT T.ID,T.TestType,COUNT(*) AS TestNum
  FROM #Person A
  INNER JOIN #TestScores T 
  ON A.TestID = T.ID
  GROUP BY T.ID,T.TestType
)
SELECT A.*
  ,T.TestType
  ,CASE
    WHEN ISNULL(N.TestType,N'') = 'test_1' AND ISNULL(N.TestNum,0)>1 THEN T.MessageLocation
    WHEN ISNULL(N.TestType,N'') = 'test_1' AND ISNULL(N.TestNum,0)>1 THEN T.AltMessageLocation
    ELSE N'' -- no tests
  END AS Loc
FROM #Person A
LEFT JOIN #TestScores T
ON A.TestID = T.ID
LEFT JOIN cteTestNum N
ON N.ID=T.ID
AND N.TestType=T.TestType;

推荐阅读