CASE表达式评估问题

时间:2016-03-30 13:34:33

标签: sql sql-server-2008 count group-by case

我有一个SQL查询,它根据描述计算CourseType,如下所示。

   SELECT    sc.EXSJ_Description,
   sn.STEN_Student_ID , s.STUD_Forename_1, s.STUD_Surname, 
    CASE 
    WHEN sc.EXSJ_Description IN ('FUNCTIONAL SKILLS - ENGLISH (LEVEL 1 & LEVEL  2)',
    'ENGLISH (ENTRY LEVEL)', 'FUNCTIONAL SKILLS ENGLISH') THEN 'Overall'
    WHEN sc.EXSJ_Description IN ('READING -ENGLISH LEVEL 2', 'READING- ENGLISH (LEVEL 1 )', 
    'E2  ENGLISH FUNTIONAL SKILLS READING', 'E2 FUNCTIONAL SKILLS READING', 
    'E3 ENGLISH FUNTIONAL SKILLS READING')THEN 'Reading' 
    WHEN sc.EXSJ_Description IN  ('WRITING- ENGLISH (LEVEL 1 )', 'WRITING- ENGLISH LEVEL  2', 
    'E2 ENGLISH FUNCTIONAL SKILLS WRITING', 'E3 ENGLISH FUNCTIONAL SKILLS WRITING') 
    THEN 'Writing' 
    WHEN sc.EXSJ_Description IN ('SPEAKING & LISTENING- 
ENGLISH LEVEL 2', 'SPEAKING & LISTENING- ENGLISH (LEVEL 1)',
    'E3 ENGLISH FUNCTIONAL SKILLS SPEAKING AND LISTENING', 
'E2 ENGLISH FUNCTIONAL SKILLS SPEAKING AND LISTENING') 
    THEN 'Speaking & Listening' 
    END AS CourseType,
    CASE WHEN e.EXSS_Act_Grade = 'PA' THEN 'Pass' 
    WHEN e.EXSS_Act_Grade = 'FL' THEN 'Fail' 
    WHEN e.EXSS_Act_Grade = 'X' THEN 'Not Attended' END AS Grade
    FROM         
    sql10.NG.dbo.STEN AS sn
LEFT OUTER JOIN sql10.NG.dbo.EXSSexmstsbj AS e 
    ON e.EXSS_Student_ID = sn.STEN_Student_ID 
    AND sn.STEN_Provision_Code = e.EXSS_Provision_Code 
    AND sn.STEN_Provision_Instance = e.EXSS_Provision_Instance
INNER JOIN sql10.NG.dbo.STUDstudent AS s 
    ON s.STUD_Student_ID = sn.STEN_Student_ID
    INNER JOIN sql10.NG.dbo.EXSJexsubject AS sc 
    ON sc.EXSJ_Subject_Code = e.EXSS_Subject_Code
WHERE (e.EXSS_Year = '2015') 
    AND (sn.STEN_Year = '2015') 
    AND (e.EXSS_Awarding_Body IN ('13', '73')) 
    AND (e.EXSS_Provision_Code LIKE 'MA27%') 
    AND (sn.STEN_Provision_Code LIKE '27%') OR
    (sn.STEN_Provision_Code LIKE 'MA27%') 
    AND (sc.EXSJ_Description LIKE '%englis%')
    GO

所以应该有3种课程类型 - 总体,阅读或写作但是当我执行查询时,我看到一些不期望的NULL值。

SQL Query Results NULL CourseType

示例数据:



CREATE TABLE [dbo].[STEN](
	[STEN_ISN] [int] IDENTITY(1,1) NOT NULL,
	[STEN_Student_ID] [char](12) NOT NULL,
	[STEN_Year] [smallint] NOT NULL,
	[STEN_Provision_Code] [char](20) NOT NULL,
	[STEN_Provision_Instance] [char](6) NOT NULL)
INSERT INTO [dbo].[STEN](
VALUES 
 (‘13068629’, ‘2015’, ‘27107’, ‘151601’),
(‘14072552   ’, ‘2015’, ‘27107’, ‘151601’),
(‘14073353’, ‘2015’, ‘27107’, ‘151601’),
(‘14073645’, ‘2015’, ‘27107/DR01’, ‘151601’),
(‘15075375’, ‘2015’, ‘27107/DR01’, ‘151601’))






CREATE TABLE [dbo].[EXSSexmstsbj](
    	[EXSS_Year] [smallint] NOT NULL,
    	[EXSS_Student_ID] [char](12) NOT NULL,
    	[EXSS_Act_Grade] [char](6) NOT NULL,
    	[EXSS_Awarding_Body] [char](16) NOT NULL,
    	[EXSS_Provision_Code] [char] (20) NULL,
    	[EXSS_Provision_Intance] [char] (6) NULL))
    INSERT INTO  dbo.EXSSexmstsbj
    VALUES  ( 2015, ‘09054118’,’PA, ‘13’, ‘MA27031/A01’, ‘151601’),
    ( 2015, ‘1261589’,’PA, ‘13’, ‘MA27031/A01’, ‘151601’),
    ( 2015, ‘1364766’,’FL, ‘13’, ‘MA27031/A01’, ‘151601’),
    ( 2015, ‘1365244’,’FL, ‘13’, ‘MA27031/A01’, ‘151601’),
    ( 2015, ‘1260791’,’X, ‘13’, ‘MA27031/A01’, ‘151601’),






CREATE TABLE [dbo].[PRPIProvisionInstance](
	[PRPI_ISN] [int] IDENTITY(1,1) NOT NULL,
	[PRPI_Code] [char](20) NOT NULL,
	[PRPI_Instance] [char](6) NOT NULL)
INSERT INTO [dbo].[PRPIProvisionInstance]
VALUES (‘19235’,’27107’,’151601’),
(‘19236’,’27107/DR01’,’151601’),
(‘19285’,‘27113’, ‘151601’),
(‘19286’,’27113/DR01’,’151601’),
(‘19237’,’27120’,’151601’)






CREATE TABLE [dbo].[PRPHProvisionHeader](
	[PRPH_Code] [char](20) NOT NULL,
	[PRPH_Title] [varchar](100) NOT NULL,
	[PRPH_ML2] [char](6) NOT NULL)
INSERT INTO [dbo].[PRPHProvisionHeader]VALUES(‘27000’,  ‘FS workshop for Art’,	‘A+D ‘),
(27000/A01’,’FS workshop for Art’,’A+D  ‘),
(‘27031/A01’,’FS English L2 (MA) (Pearson)’,’ WFD ‘),
(‘27032/A01’,’FS Maths L2 (MA) (Pearson)’,’ WFD ‘) ,
(‘27100/E91’,’EDEX English E1 FS Sept Start (13195) Tue 6.00-9.00’,’ PLW  ‘)






CREATE TABLE [dbo].[STUDstudent](
	[STUD_Student_ID] [char](12) NOT NULL,
	[STUD_Surname] [varchar](30) NOT NULL,
	[STUD_Forename_1] [varchar](20) NOT NULL,
	)	
INSERT INTO [dbo].[STUDstudent]
(‘703666V’, ‘Aakel’,’Gail’),
(‘472833M’,’Abbott’,’Emma’),
(‘481691M’,’Abbasi’,’Anisa’),
‘13072746’,’Ababio’,’Anita’),
‘13070877’,’Aaronson’,	‘Fay’)






CREATE TABLE [dbo].[EXSJexsubject](
	[EXSJ_Description] [varchar](100) NOT NULL,
	[EXSJ_Awarding_Body] [char](16) NOT NULL,
	)
INSERT INTO [dbo].[EXSJexsubject]
VALUES (‘E1  ENGLISH FUNCTIONAL SKILLS SPEAKING AND LISTENING’,	‘13‘),
(‘E1 ENGLISH FUNTIONAL SKILLS READING’,’ 13 ‘),
(‘E1 ENGLISH FUNCTIONAL SKILLS WRITING’,’ 13 ‘),        
(‘E2 ENGLISH FUNCTIONAL SKILLS SPEAKING AND LISTENING’,’13’),              
(‘E2  ENGLISH FUNTIONAL SKILLS READING’,’ 13 ‘)             






CREATE TABLE [dbo].[GNUCustom](
	[GNUC_Type] [char](4) NOT NULL,
	[GNUC_Entity_ISN] [int] NOT NULL,
GNUC_Text_1 [VARCHAR] (100) NOT NULL)

INSERT INTO VALUES
(PRPI	571	
PRPI	7761	
PRPI	8292	
PRPI	8346	
PRPI	8374	
)




请建议我哪里出错。

谢谢, 的Ar

3 个答案:

答案 0 :(得分:2)

我猜想EXSJ_Description列中还有一些其他值未在CASE WHEN语句中被提取。

尝试此命令,看看它是否返回任何非空值:

SELECT  
     EXSJ_Description
FROM 
     sql10.NG.dbo.EXSJexsubject
WHERE 
     EXSJ_Description
     NOT IN 
         ('FUNCTIONAL SKILLS - ENGLISH (LEVEL 1 & LEVEL  2)',
         'ENGLISH (ENTRY LEVEL)',
         'FUNCTIONAL SKILLS ENGLISH',
         'WRITING- ENGLISH (LEVEL 1 )',
         'WRITING- ENGLISH LEVEL  2',
         'E2 ENGLISH FUNCTIONAL SKILLS WRITING',
         'E3 ENGLISH FUNCTIONAL SKILLS WRITING',
         'SPEAKING & LISTENING- ENGLISH LEVEL 2',
         'SPEAKING & LISTENING- ENGLISH (LEVEL 1)',
         'E3 ENGLISH FUNCTIONAL SKILLS SPEAKING AND LISTENING',
         'E2 ENGLISH FUNCTIONAL SKILLS SPEAKING AND LISTENING')

如果有,请将它们添加到您的条件中。将来,最佳实践要求始终使用ELSE来捕获任何不匹配的值。

如果它们都为null,则您的连接可能会导致重复创建额外空值的数据。没有您的数据集,很难确定。

答案 1 :(得分:1)

虽然在某些情况下使用完全匹配可能是合乎需要的,但是拥有完全匹配的列表会提供拼写错误的机会,并可能在将来导致维护问题。

您可以考虑在此处使用模式匹配来使代码更容易理解:

(CASE WHEN sc.EXSJ_Description LIKE 'FUNCTIONAL%' OR 
           sc.EXSJ_Description LIKE '%ENTRY%'
     THEN 'Overall'
     WHEN sc.EXSJ_Description LIKE '%READING%'
     THEN 'Reading' 
     WHEN sc.EXSJ_Description LIKE '%WRITING%'
     THEN 'Writing' 
     WHEN sc.EXSJ_Description LIKE '%SPEAKING%LISTENING%'
     THEN 'Speaking & Listening' 
     ELSE 'Unknown'
END) AS CourseType,

不可否认,这不适用于所有命名约定(如果说明同时包含READINGWRITING,那么是什么?)。但它确实适用于您的特定名称,它减少了拼写错误的机会,这导致了您的原始问题。

答案 2 :(得分:1)

尝试这一点,但从性能角度来看并不好

CASE
    WHEN REPLACE(sc.EXSJ_Description,' ','') IN (
                        REPLACE('FUNCTIONAL SKILLS - ENGLISH (LEVEL 1 & LEVEL  2)',' ',''),
                        REPLACE('ENGLISH (ENTRY LEVEL)',' ',''),
                        REPLACE('FUNCTIONAL SKILLS ENGLISH',' ','')
                    ) THEN 'Overall'
    WHEN REPLACE(sc.EXSJ_Description,' ','') IN (
                       REPLACE('READING -ENGLISH LEVEL 2',' ',''),
                       REPLACE('READING- ENGLISH (LEVEL 1 )',' ',''), 
                       REPLACE('E2  ENGLISH FUNTIONAL SKILLS READING',' ',''),        
                       REPLACE('E2 FUNCTIONAL SKILLS READING',' ','') 
                       REPLACE('E3 ENGLISH FUNTIONAL SKILLS READING',' ','')
                   )THEN 'Reading' 
    WHEN REPLACE(sc.EXSJ_Description,' ','') IN  (
                       REPLACE('WRITING- ENGLISH (LEVEL 1 )',' ',''),
                       REPLACE('WRITING- ENGLISH LEVEL  2',' ',''), 
                       REPLACE('E2 ENGLISH FUNCTIONAL SKILLS WRITING',' ',''), 
                       REPLACE('E3 ENGLISH FUNCTIONAL SKILLS WRITING',' ','')
                   )THEN 'Writing' 
    ...
    ...