簡體   English   中英

案例陳述中的案例

[英]Case within Case statement

我必須從稱為“節”的表中獲得教師批准的日期。 如果該表沒有日期(空),那么我必須從提供表中獲取日期,即使該表沒有我想要的內容,也可以從Term表中獲取日期。

並且如果所有三個都為空,那么我需要以與執教者批准日期相同的方式獲取absoluteExpireDate。

並且,如果在所有三個表中absoluteExpireDate也為null,那么我需要以類似的方式獲取WaitList日期。

如何創建一個case語句來處理呢?

到目前為止,這是我所擁有的:

SELECT  @dInstructApprDate = case when a.InstructorApprovalDate is null  
        then
             select @dInstructApprDate = instructorapprovaldate 
             from SSS_OfferingAcademicPeriods   
             where SSS_OfferingRegPeriods.SSS_OfferingsID = @lSSS_OfferingsID

我不確定為什么在“ THEN”中使用select語句不喜歡我

任何幫助,將不勝感激。

這是我到目前為止獲得的功能:

 CREATE FUNCTION [dbo].[SSS_GetInstructorApprovalDate](@lSSS_SectionsID INT)      
 RETURNS VARCHAR(20)    
 AS      

          BEGIN      

  DECLARE   
 @dInstructApprDate DATETIME,  
 @dAddDropDate  DATETIME,  
 @lTemp    INT,  
 @lSSS_OfferingsID INT,  
 @lSSS_TermsID  INT  

 SET @lTemp = 0  

 SELECT   
 @lTemp = 1  
 WHERE   
 EXISTS (SELECT 1 FROM SSS_SectionAcademicPeriods WITH (NOLOCK) WHERE SSS_SectionsID = @lSSS_SectionsID)  

--Fetch from section level, if present - Begin  
 IF @lTemp = 1  
BEGIN  

  SELECT  @dInstructApprDate = case when a.InstructorApprovalDate is null  
  then   
   (select instructorapprovaldate from SSS_OfferingAcademicPeriods where SSS_OfferingRegPeriods.SSS_OfferingsID = @lSSS_OfferingsID)

  else   
 InstructorApprovalDate  
end   
  FROM  
   SSS_SectionAcademicPeriods a WITH (NOLOCK)  
  where   
   SSS_SectionsID = @lSSS_SectionsID

有點不好說,而無需整個查詢,什么a代表什么嗎? 看起來您的case是較大查詢的一部分,但是

SELECT
    @dInstructApprDate = 
         case
             when a.InstructorApprovalDate is null  
             then 
             (
                 select o.InstructorApprovalDate 
                 from SSS_OfferingAcademicPeriods as o
                 where o.SSS_OfferingsID = @lSSS_OfferingsID
             )
-- ...
-- you have from clause here?
-- ...

我認為您的查詢可以大大簡化,但是直到我看到整個查詢后才能說

更新

select @dInstructApprDate = InstructorApprovalDate
from SSS_SectionAcademicPeriods
where SSS_SectionsID = @lSSS_SectionsID

if @dInstructApprDate is null
    select @dInstructApprDate = instructorapprovaldate
    from SSS_OfferingAcademicPeriods
    where SSS_OfferingsID = @lSSS_OfferingsID

每個選擇只需要一個變量分配,例如

SELECT  @dInstructApprDate = case when a.InstructorApprovalDate is null  
        then  (select  instructorapprovaldate from SSS_OfferingAcademicPeriods)
....

但是最好將其拆分為單獨的選擇-易於閱讀,易於維護,更易於服務器執行,例如

SELECT  @dInstructApprDate = InstructorApprovalDate FROM section

IF @dInstructApprDate IS NULL -- if it's null after first assignmnent
     SELECT  @dInstructApprDate = InstructorApprovalDate FROM SSS_OfferingAcademicPeriods

IF @dInstructApprDate IS NULL -- if it's still null
     SELECT  @dInstructApprDate = TermDate FROM Term

在這種情況下,您應該使用IF語句

CASE用於選擇標量值 (也可以通過查詢來檢索)。 可以使用IF以更易讀的方式為相關案例選擇相關查詢。

您的代碼應如下所示(偽):

IF(Some condition)
BEGIN
     SELECT ...
     FROM...   

END
ELSE IF (Some condition)
BEGIN
    SELECT ...
    FROM...   
END

假設您要檢查是否為空,則可以使用Coalesce

select coalesce
(
      (select 1 a where 1=2) --returns null
    , (select 2 a where 2=3) --returns null
    , (select 3 a where 4=4) --returns result
    , 100 --default
) x

對我來說,這比一個案例陳述更干凈/更容易理解,我懷疑它的表現也一樣。

根據您問題中包含的代碼和描述,對您來說,這看起來像以下內容:

CREATE FUNCTION [dbo].[SSS_GetInstructorApprovalDate](@lSSS_SectionsID INT)      
RETURNS VARCHAR(20)    
AS      
BEGIN      

    DECLARE @dInstructApprDate  DATETIME 
    ,       @dAddDropDate       DATETIME
    ,       @lSSS_OfferingsID   INT
    ,       @lSSS_TermsID       INT  
    --,     @lTemp              INT = 0

    --I suspect you don't want this bit; but uncomment if it's required (i.e. if you only want a value when there's a matching record in the secion table, but the record's approval date's null
    --SELECT top 1 @lTemp = 1 
    --FROM SSS_SectionAcademicPeriods WITH (NOLOCK) 
    --WHERE SSS_SectionsID = @lSSS_SectionsID

    --Fetch from section level, if present - Begin  
    --IF @lTemp = 1  
    --BEGIN  

        SELECT @dInstructApprDate = coalesce
        (
            (
                SELECT InstructorApprovalDate       
                FROM SSS_SectionAcademicPeriods with(nolock)
                where SSS_SectionsID = @lSSS_SectionsID
            )
            ,
            (
                select InstructorApprovalDate 
                from SSS_OfferingAcademicPeriods 
                where SSS_OfferingsID = @lSSS_OfferingsID
            )
            ,
            (
                select InstructorApprovalDate 
                from SSS_TermsAcademicPeriods 
                where SSS_OfferingsID = @lSSS_TermsID
            )

            ,
            (
                SELECT AbsoluteExpireDate       
                FROM SSS_SectionAcademicPeriods with(nolock)
                where SSS_SectionsID = @lSSS_SectionsID
            )
            ,
            (
                select AbsoluteExpireDate        
                from SSS_OfferingAcademicPeriods 
                where SSS_OfferingsID = @lSSS_OfferingsID
            )
            ,
            (
                select AbsoluteExpireDate        
                from SSS_TermsAcademicPeriods 
                where SSS_OfferingsID = @lSSS_TermsID
            )
            ,
            (
                SELECT WaitListDate     
                FROM SSS_SectionAcademicPeriods with(nolock)
                where SSS_SectionsID = @lSSS_SectionsID
            )
            ,
            (
                select WaitListDate      
                from SSS_OfferingAcademicPeriods 
                where SSS_OfferingsID = @lSSS_OfferingsID
            )
            ,
            (
                select WaitListDate      
                from SSS_TermsAcademicPeriods 
                where SSS_OfferingsID = @lSSS_TermsID
            )

        )
    --END
    return cast(@dInstructApprDate as varchar(20)) --probably 

END

注意:根據每個查詢所花費的時間,您可能需要略微不同的方法。 這是另一種選擇/讓我知道它的適合方式:

CREATE FUNCTION [dbo].[SSS_GetInstructorApprovalDate](@lSSS_SectionsID INT)      
RETURNS VARCHAR(20)    
AS      
BEGIN      

    DECLARE @dInstructApprDate  DATETIME 
    ,       @dInstructApprDate2 DATETIME 
    ,       @dInstructApprDate3 DATETIME 
    ,       @dAddDropDate       DATETIME
    ,       @lSSS_OfferingsID   INT
    ,       @lSSS_TermsID       INT  
    --,     @lTemp              INT = 0

    --I suspect you don't want this bit; but uncomment if it's required (i.e. if you only want a value when there's a matching record in the secion table, but the record's approval date's null
    --SELECT top 1 @lTemp = 1 
    --FROM SSS_SectionAcademicPeriods WITH (NOLOCK) 
    --WHERE SSS_SectionsID = @lSSS_SectionsID

    --Fetch from section level, if present - Begin  
    --IF @lTemp = 1  
    --BEGIN  


        SELECT  @dInstructApprDate  = InstructorApprovalDate        
        ,       @dInstructApprDate2 = AbsoluteExpireDate
        ,       @dInstructApprDate3 = WaitListDate
        FROM SSS_SectionAcademicPeriods with(nolock)
        where SSS_SectionsID = @lSSS_SectionsID

        if @dInstructApprDate is null 
            select  @dInstructApprDate  = InstructorApprovalDate        
            ,       @dInstructApprDate2 = isnull(@dInstructApprDate2, AbsoluteExpireDate)
            ,       @dInstructApprDate3 = isnull(@dInstructApprDate3, WaitListDate)
            from SSS_OfferingAcademicPeriods 
            where SSS_OfferingsID = @lSSS_OfferingsID

        if @dInstructApprDate is null 
            select  @dInstructApprDate  = InstructorApprovalDate    
            ,       @dInstructApprDate2 = isnull(@dInstructApprDate2, AbsoluteExpireDate)
            ,       @dInstructApprDate3 = isnull(@dInstructApprDate3, WaitListDate
            from SSS_TermsAcademicPeriods 
            where SSS_OfferingsID = @lSSS_TermsID


        set @dInstructApprDate = coalesce(@dInstructApprDate, @dInstructApprDate2, @dInstructApprDate3)

    --END
    return cast(@dInstructApprDate as varchar(20)) --probably 

END

如下所示使用CASE WHEN ... THEN ... ELSE ... END 由於要從第一次遇到的表中獲取值,因此需要首先檢查IS NOT NULL 如果該值NOT NULLCASE語句將在此處停止。

這正是COALESCE工作方式。 因此,您可以將CASE語句替換為COALESCE

觀看演示-

SQL小提琴

MS SQL Server 2008架構設置

CREATE TABLE t1 (     id int    , type varchar(50)    );
CREATE TABLE t2 (     id int    , type varchar(50)    );
CREATE TABLE t3 (     id int    , type varchar(50)    );


insert into t1 values (1, 'one');
insert into t1 values (10, null);
insert into t1 values (15, null);
insert into t1 values (20, null);
insert into t2 values (10, 'ten from table t2');
insert into t3 values (15, 'fifteen from table t3');

查詢1

SELECT id,
       CASE WHEN TYPE IS NOT NULL THEN TYPE
       WHEN  (SELECT TYPE FROM t2 WHERE t2.id = t1.id) IS NOT NULL
            THEN (SELECT TYPE FROM t2 WHERE t2.id = t1.id)
       ELSE  (SELECT TYPE FROM t3 WHERE t3.id = t1.id)
       END
FROM t1

結果

| ID |              COLUMN_1 |
|----|-----------------------|
|  1 |                   one |
| 10 |     ten from table t2 |
| 15 | fifteen from table t3 |
| 20 |                (null) |

查詢2

SELECT id, 
      COALESCE(TYPE,
              (SELECT TYPE FROM t2 WHERE t2.id = t1.id),
              (SELECT TYPE FROM t3 WHERE t3.id = t1.id))
FROM t1

結果

| ID |              COLUMN_1 |
|----|-----------------------|
|  1 |                   one |
| 10 |     ten from table t2 |
| 15 | fifteen from table t3 |
| 20 |                (null) |

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM