2013-09-26 58 views
3

我怀疑这与我在SELECT语句中有case语句并且然后尝试对此执行GROUP BY和ORDER BY语句的事实有关。SQL条件选择大小写逻辑

我有一个基于两个表之间的连接的结果集。一个是ks2en,ks2ma和Ks2av列值为2c,2b,2a,3c,3b等的学生表,第二个是每个学生的结果表,例如A +,A,A-,B +等。对ks2en,ks2ma和Ks2av列进行分组,并将结果相加,得出一个总数的网格,其中左下方的水平和上方的结果。然而,三种级别Ks2en,Ks2ma和Ks2av应该基于一个特定的主题,通过结果带来:

Ks2en - English Result 
Ks2ma - Maths Result 
Ks2av - Any other subject Result 

哪里有在ks2en,ks2ma或ks2av列没有价值,我想小组通过向显示为'没有KS2'。

我的代码在底部对于Ks2en的英语非常出色,但我正在努力根据主题是英语,数学还是其他来改变结果的逻辑。

该主题通过名为@SubjectName的变量进行填充。

下面是伪代码,我想我的SQL做的事:

If @SubjectName = 'English' then 
    If ks2en ='' then 
     display 'No KS2' 
    else Ks2en 
    endif 
Else if @SubjectName = 'Mathematics' then 
    If ks2ma ='' then 
     display 'No KS2' 
    else Ks2ma 
    endif 
Else if @SubjectName <> 'English' and @SubjectName <> 'Mathematics' then 
    If ks2av ='' then 
     display 'No KS2' 
    else Ks2av 
    endif 

这是到目前为止我的代码是工作时@SubjectName = '英语':

DECLARE 
@DataCollection varchar(50) = '2013/14 - Autumn 1 - Targets', 
@StuYear VARCHAR(2) = '11', 
@SubjectName varchar(100) ='English', 
@TeachingGroup varchar(25) = 'Select All', 
@SubGroup varchar(10) = 'Select All' 
SELECT CASE WHEN Ks2en = '' and @SubjectName = 'English' THEN 'No KS2' ELSE ks2en END AS 'KS2', 
     nullif(count(CASE WHEN result = '' THEN 1 END),0) AS 'No Level/Grade', 
     nullif(count(CASE WHEN result IN ('U', '1a', '1b', '1c') THEN 1 END),0) AS '1/U', 
     nullif(count(CASE WHEN result IN ('U', '2a', '2b', '2c') THEN 1 END),0) AS '2/U', 
     nullif(count(CASE WHEN result IN ('G-','3c') THEN 1 END),0) AS '3c/G-', 
     nullif(count(CASE WHEN result IN ('G', '3b') THEN 1 END),0) AS '3b/G', 
     nullif(count(CASE WHEN result IN ('G+','3a') THEN 1 END),0) AS '3a/G+', 
     nullif(count(CASE WHEN result IN('F-','4c') THEN 1 END),0) AS '4c/F-', 
     nullif(count(CASE WHEN result IN('F', '4b') THEN 1 END),0) AS '4b/F', 
     nullif(count(CASE WHEN result IN('F+', '4a') THEN 1 END),0) AS '4a/F+', 
     nullif(count(CASE WHEN result IN('E-', '5c') THEN 1 END),0) AS '5c/E-', 
     nullif(count(CASE WHEN result IN('E', '5b') THEN 1 END),0) AS '5b/E', 
     nullif(count(CASE WHEN result IN('E+', '5a') THEN 1 END),0) AS '5a/E+', 
     nullif(count(CASE WHEN result IN('D-', '6c') THEN 1 END),0) AS '6c/D-', 
     nullif(count(CASE WHEN result IN('D', '6b') THEN 1 END),0) AS '6b/D', 
     nullif(count(CASE WHEN result IN('D+', '6a') THEN 1 END),0) AS '6a/D+',  
     nullif(count(CASE WHEN result IN('C-', '7c') THEN 1 END),0) AS '7c/C-',  
     nullif(count(CASE WHEN result IN('C', '7b') THEN 1 END),0) AS '7b/C',  
     nullif(count(CASE WHEN result IN('C+', '7a') THEN 1 END),0) AS '7a/C+',   
     nullif(count(CASE WHEN result IN('B-', '8c') THEN 1 END),0) AS '8c/B-', 
     nullif(count(CASE WHEN result IN('B', '8b') THEN 1 END),0) AS '8b/B', 
     nullif(count(CASE WHEN result IN('B+', '8a') THEN 1 END),0) AS '8a/B+', 
     nullif(count(CASE result WHEN 'A-' THEN 1 END),0) AS 'A-', 
     nullif(count(CASE result WHEN 'A' THEN 1 END),0) AS 'A', 
     nullif(count(CASE result WHEN 'A+' THEN 1 END),0) AS 'A+', 
     nullif(count(CASE result WHEN 'A*-' THEN 1 END),0) AS 'A*-', 
     nullif(count(CASE result WHEN 'A*' THEN 1 END),0) AS 'A*' 
    FROM student JOIN subject 
    ON subject.upn=student.upn 
WHERE 
    [StuYear] = @StuYear AND 
    [DataCollection] = @DataCollection AND 
    [Name] = @SubjectName AND (
     @TeachingGroup = 'Select All' OR 
     [TeachingGroup] = @TeachingGroup 
    ) AND (
     @SubGroup = 'Select All' OR 
     Gender = CASE 
       WHEN @SubGroup = 'GenF' THEN 'F' 
       WHEN @SubGroup = 'GenM' THEN 'M' 
      END 
    ) 
GROUP BY ks2en 
ORDER BY 
    CASE WHEN ks2en = 'W' THEN 0 ELSE 1 END, 
    LEFT(ks2en, 1), 
    RIGHT(ks2en, 1) DESC 

如果@ SubjectName ='Mathematics'然后该语句将有效地执行以下操作:

DECLARE 
@DataCollection varchar(50) = '2013/14 - Autumn 1 - Targets', 
@StuYear VARCHAR(2) = '11', 
@SubjectName varchar(100) ='Mathematics', 
@TeachingGroup varchar(25) = 'Select All', 
@SubGroup varchar(10) = 'Select All' 
SELECT CASE WHEN Ks2ma = '' and @SubjectName = 'Mathematics' THEN 'No KS2' ELSE ks2ma END AS 'KS2', 
     nullif(count(CASE WHEN result = '' THEN 1 END),0) AS 'No Level/Grade', 
**SNIP** 
     nullif(count(CASE result WHEN 'A*' THEN 1 END),0) AS 'A*' 
    FROM student JOIN subject 
    ON subject.upn=student.upn 
WHERE 
    [StuYear] = @StuYear AND 
    [DataCollection] = @DataCollection AND 
    [Name] = @SubjectName AND (
     @TeachingGroup = 'Select All' OR 
     [TeachingGroup] = @TeachingGroup 
    ) AND (
     @SubGroup = 'Select All' OR 
     Gender = CASE 
       WHEN @SubGroup = 'GenF' THEN 'F' 
       WHEN @SubGroup = 'GenM' THEN 'M' 
      END 
    ) 
GROUP BY ks2ma 
ORDER BY 
    CASE WHEN ks2ma = 'W' THEN 0 ELSE 1 END, 
    LEFT(ks2ma, 1), 
    RIGHT(ks2ma, 1) DESC 

如果@Subject名称等于别的如科学,艺术或技术,则SQL会想以下几点:

DECLARE 
@DataCollection varchar(50) = '2013/14 - Autumn 1 - Targets', 
@StuYear VARCHAR(2) = '11', 
@SubjectName varchar(100) ='Science', 
@TeachingGroup varchar(25) = 'Select All', 
@SubGroup varchar(10) = 'Select All' 
SELECT CASE WHEN Ks2av = '' and @SubjectName <> 'Mathematics' and @SubjectName <> 'English' THEN 'No KS2' ELSE ks2av END AS 'KS2', 
     nullif(count(CASE WHEN result = '' THEN 1 END),0) AS 'No Level/Grade', 
**SNIP** 
     nullif(count(CASE result WHEN 'A*' THEN 1 END),0) AS 'A*' 
    FROM student JOIN subject 
    ON subject.upn=student.upn 
WHERE 
    [StuYear] = @StuYear AND 
    [DataCollection] = @DataCollection AND 
    [Name] = @SubjectName AND (
     @TeachingGroup = 'Select All' OR 
     [TeachingGroup] = @TeachingGroup 
    ) AND (
     @SubGroup = 'Select All' OR 
     Gender = CASE 
       WHEN @SubGroup = 'GenF' THEN 'F' 
       WHEN @SubGroup = 'GenM' THEN 'M' 
      END 
    ) 
GROUP BY ks2av 
ORDER BY 
    CASE WHEN ks2av = 'W' THEN 0 ELSE 1 END, 
    LEFT(ks2av, 1), 
    RIGHT(ks2av, 1) DESC 

我的SQL生成网格类似于以下。结果集将看看SMAE但后台数据将基于上述不同的标准,并会在每个小区产生不同的总计:

KS2 No Result 1/U  2/U  3c/G- 3b/G 3a/G+ 4c/F- 4b/F **snip** 
No KS2   1  NULL NULL NULL NULL NULL NULL **snip** 
2a NULL  NULL NULL NULL NULL NULL 2  1  **snip** 
3c 1   NULL NULL NULL NULL NULL NULL NULL **snip** 
3b NULL  NULL NULL NULL NULL NULL 1  NULL **snip** 
3a 1   NULL NULL NULL NULL NULL NULL NULL **snip** 
4c NULL  1  1  NULL NULL NULL NULL NULL **snip** 
4b NULL  NULL NULL NULL NULL NULL NULL NULL **snip** 
4a NULL  1  1  NULL NULL NULL NULL NULL **snip** 
5c NULL  NULL NULL NULL NULL NULL NULL NULL **snip** 
5b NULL  NULL NULL NULL NULL NULL NULL NULL **snip** 
+0

“*** g^- ***” ???哇,你有一些艰难的评分。 – RBarryYoung

回答

1

如果我深知,你其实可以处理所有任务你自己除了过滤。我的意思是,除了用“英语/数学/其他”分支/调整结果外,你的问题与事实是几乎相同的,除了它们来自不同的列并且你想要统一地对它们进行线程化。

对不起,如果这不是你的实际问题,但我读/理解它的方式。

我目前不能给你一个确切的完整答案,由于几个原因(即我不知道如何等级F + G-等与3a6b值),但我至少可以给你一些帮助/启动你如何解决这类问题。

您想要的效果:

 If @SubjectName = 'English' then If ks2en ='' then .... 
else If @SubjectName = 'Maths' then If ks2ma ='' then .... 
else          If ks2av ='' then .... 

它很容易被一些初步的重新安排你的输入表来完成。简单地说,有趣的部分只是过滤成块,并添加一些常量,将作为有关块一个方便的元数据:

  select "English"  as topic, ks2en as ks2 
      from YourTable 
      where ks2en <> '' 
union all 
      select "Mathematics" as topic, ks2ma as ks2 
      from YourTable 
      where ks2ma <> '' 
union all 
      select "Other"  as topic, ks2av as ks2 
      from YourTable 
      where ks2av <> '' 

注意,我增加了额外的计算键值名为topic,但是这些数据现在被重新安排分成2列。您现在不能区分ks2enks2ma,但是您有一个ks2,您可以通过常量topic列检测结果。

现在:

select 
    case when subq.ks2 = '' then 'No KS2' 
    else subq.ks2 
    end 
from 
(
      select "English"  as topic, ks2en as ks2 from YourTable where ks2en <> '' 
union all select "Mathematics" as topic, ks2ma as ks2 from YourTable where ks2ma <> '' 
union all select "Other"  as topic, ks2av as ks2 from YourTable where ks2av <> '' 
) subq 
where subq.topic = @SubjectName 

(我已经压实选择/工会一部分整体可读性)

将返回KS2的实际SubjectName你想要的。除了Other部分显然不匹配任何东西,因为“物理”不符合“其他”。您可以通过检查SubjectName中的已知值并将其设置为“Other”来轻松解决问题。或者别的什么。

关键是,由于初步的过滤器描述和粘贴它可以以任何你想要的方式重塑数据,然后很容易地将它组合/投影到你想要的东西上。

编辑:我不知道它是否存在于sql2008级别,但我认为你也可以检查PIVOT/UNPIVOT操作符,可以转置列< - >行。他们使用起来很棘手,有一些限制,使他们远不如他们可以得到的方便,但值得检查。当然,假设我很好地理解了你的问题的核心。对不起,对不起。

+0

感谢您花时间回答。我发现很难尽可能简单地表达我的问题而不会漏掉任何东西。我会再看看我的问题,并尝试使它更清晰一些。我会尝试使用一些示例数据。 – Matt

1

如果我理解您的问题,您希望您的KS2列显示相关主题的相关KS2__数据。尝试:

CASE 
    WHEN (Ks2en = '' and @SubjectName = 'English') 
     OR (Ks2ma = '' and @SubjectName = 'Mathematics') 
     OR (Ks2av = '' and @SubjectName <> 'Mathematics' and @SubjectName <> 'English') 
    THEN 'No KS2' 
    ELSE CASE @SubjectName 
       WHEN 'English' THEN Ks2en 
       WHEN 'Mathematics' THEN Ks2ma 
       ELSE Ks2av 
     END 
END AS KS2 

你会使用这个条款(少AS KS2)在GROUP BY和类似的条款在您的ORDER BY

ORDER BY 
CASE WHEN 
    CASE 
      WHEN (Ks2en = '' and @SubjectName = 'English') 
       OR (Ks2ma = '' and @SubjectName = 'Mathematics') 
       OR (Ks2av = '' and @SubjectName <> 'Mathematics' and @SubjectName <> 'English') 
      THEN 'No KS2' 
      ELSE CASE @SubjectName 
         WHEN 'English' THEN Ks2en 
         WHEN 'Mathematics' THEN Ks2ma 
         ELSE Ks2av 
       END 
     END = 'W' THEN 0 ELSE 1 END, 
    LEFT(CASE 
      WHEN (Ks2en = '' and @SubjectName = 'English') 
       OR (Ks2ma = '' and @SubjectName = 'Mathematics') 
       OR (Ks2av = '' and @SubjectName <> 'Mathematics' and @SubjectName <> 'English') 
      THEN 'No KS2' 
      ELSE CASE @SubjectName 
         WHEN 'English' THEN Ks2en 
         WHEN 'Mathematics' THEN Ks2ma 
         ELSE Ks2av 
       END 
     END, 1), 
    RIGHT(CASE 
      WHEN (Ks2en = '' and @SubjectName = 'English') 
       OR (Ks2ma = '' and @SubjectName = 'Mathematics') 
       OR (Ks2av = '' and @SubjectName <> 'Mathematics' and @SubjectName <> 'English') 
      THEN 'No KS2' 
      ELSE CASE @SubjectName 
         WHEN 'English' THEN Ks2en 
         WHEN 'Mathematics' THEN Ks2ma 
         ELSE Ks2av 
       END 
     END, 1) DESC