[英]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 NULL
則CASE
語句將在此處停止。
這正是COALESCE
工作方式。 因此,您可以將CASE
語句替換為COALESCE
觀看演示-
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.