如何包含CASE IF THEN语句SQL

时间:2017-04-06 17:46:13

标签: sql sql-server tsql

我正在尝试在下面的存储过程中创建一个case语句。我希望@OHDept执行以下操作:

如果部门= 15,则显示16

我尝试的所有内容都会给我一些错误,例如"在预期条件的比赛中指定的非布尔类型的表达式,接近"否则"。

我知道我做错了什么,但我不确定是什么。有人能帮我吗? 谢谢!

(@JCCo bCompany,  @BeginContract bContract ='', @EndContract bContract= 'zzzzzzzzz', @ThroughMth bDate,@BegMth bDate,@BegDept bDept='', @EndDept bDept='zzzzzzzzzz', @Status char(1)='A', @BegMthClosed bDate, @EndMthClosed bDate)

With Recompile   
as
set nocount on

declare @OHDept varchar(2)


declare @CT1Desc varchar(5), @CT2Desc varchar(5), @CT3Desc varchar(5),
@CT4Desc varchar(5), @CT5Desc varchar(5), @CT6Desc varchar(5),
@CT7Desc varchar(5), @CT8Desc varchar(5), @CT9Desc varchar(5)

select @CT1Desc=JCCT.Abbreviation 
from HQCO
join JCCT WITH (NOLOCK) on HQCO.PhaseGroup=JCCT.PhaseGroup 
Where HQCO.HQCo=@JCCo and JCCT.CostType=1
select @CT2Desc=JCCT.Abbreviation 
from HQCO
join JCCT WITH (NOLOCK) on HQCO.PhaseGroup=JCCT.PhaseGroup 
Where HQCO.HQCo=@JCCo and JCCT.CostType=2
select @CT3Desc=JCCT.Abbreviation 
from HQCO
join JCCT WITH (NOLOCK) on HQCO.PhaseGroup=JCCT.PhaseGroup 
Where HQCO.HQCo=@JCCo and JCCT.CostType=3
select @CT4Desc=JCCT.Abbreviation 
from HQCO
join JCCT WITH (NOLOCK) on HQCO.PhaseGroup=JCCT.PhaseGroup 
Where HQCO.HQCo=@JCCo and JCCT.CostType=4
select @CT5Desc=JCCT.Abbreviation 
from HQCO
join JCCT WITH (NOLOCK) on HQCO.PhaseGroup=JCCT.PhaseGroup 
Where HQCO.HQCo=@JCCo and JCCT.CostType=5
select @CT6Desc=JCCT.Abbreviation 
from HQCO
join JCCT WITH (NOLOCK) on HQCO.PhaseGroup=JCCT.PhaseGroup 
Where HQCO.HQCo=@JCCo and JCCT.CostType=6
select @CT7Desc=JCCT.Abbreviation 
from HQCO
join JCCT WITH (NOLOCK) on HQCO.PhaseGroup=JCCT.PhaseGroup 
Where HQCO.HQCo=@JCCo and JCCT.CostType=7
select @CT8Desc=JCCT.Abbreviation 
from HQCO
join JCCT WITH (NOLOCK) on HQCO.PhaseGroup=JCCT.PhaseGroup 
Where HQCO.HQCo=@JCCo and JCCT.CostType=99
select @CT9Desc=JCCT.Abbreviation 
from HQCO
join JCCT WITH (NOLOCK) on HQCO.PhaseGroup=JCCT.PhaseGroup 
Where HQCO.HQCo=@JCCo and JCCT.CostType=9
set nocount off;


With Contracts (JCCo, Contract) 
as (select JCCo, 
Contract 
From   JCCM 
Where  JCCo = @JCCo 
and ( 
  ------------------------ 
  /*Open*/ 
  case @Status 
    when 'O' then ContractStatus 
  end = 1 
   or /*Open*/ 
  case @Status 
    when 'O' then ContractStatus 
  end = 2 
  and MonthClosed > @ThroughMth 
   or /*Open*/ 
  case @Status 
    when 'O' then ContractStatus 
  end = 3 
  and MonthClosed > @ThroughMth 
   ------------------------ 
   or /*Soft-Closed/Open*/ 
  case @Status 
    when 'S' then ContractStatus 
  end = 2 
  and MonthClosed <= @ThroughMth 
   or /*Soft-Closed/Open*/ 
  case @Status 
    when 'S' then ContractStatus 
  end = 1 
   or /*Soft-Closed/Open*/ 
  case @Status 
    when 'S' then ContractStatus 
  end = 2 
  and MonthClosed > @ThroughMth 
   or /*Soft-Closed/Open*/ 
  case @Status 
    when 'S' then ContractStatus 
  end = 3 
  and MonthClosed > @ThroughMth 
   ------------------------ 
   or /*Hard-Closed*/ 
  case @Status 
    when 'C' then ContractStatus 
  end = 3 
  and MonthClosed between @BegMthClosed and @EndMthClosed 
   ------------------------   
   or
  case @Status 
    when 'A' then ContractStatus 
  end <> 0 )
) --End CTE 


Select 'CT1Desc'=@CT1Desc, 'CT2Desc'=@CT2Desc, 'CT3Desc'=@CT3Desc,'CT4Desc'=@CT4Desc, 
'CT5Desc'=@CT5Desc,'CT6Desc'= @CT6Desc, 'CT7Desc'=@CT7Desc, 'CT8Desc'=@CT8Desc,'CT9Desc'=@CT9Desc,

ProjectMngrID=JCJMPM.ProjectMgr, --3/11/16 CJO
PrjDept=JCCM.Department, ---3/11/16 CJO
PrjVP=JCCM.udProjectManager, --3/25/16 CJO

JCCM.JCCo, JCCM.Contract, ContDesc=JCCM.Description, JCCM.ContractStatus,
JCCI.Department, DeptDesc = JCDM.Description,
JCIP.BilledAmt,
JCIP.ReceivedAmt,ActualCost,ACost1,ACost2,ACost3,ACost4,ACost5,ACost6,ACost7,ACost8,ACost9,
ProjCloseDate=JCCM.ProjCloseDate,
StartMonth=JCCM.StartMonth,---7/5/02 AA
MonthClosed=JCCM.MonthClosed,---7/5/02 AA
ContractDays=JCCM.CurrentDays,
JobItem=JCJMPM.Job,
CoName=HQCO.Name,
BeginContract=@BeginContract,
EndContract=@EndContract,
ThroughMth=@ThroughMth,
BegMth=@BegMth/*, JCCM.Notes*/

FROM JCCI WITH (NOLOCK)
JOIN JCCM WITH (NOLOCK) on JCCM.JCCo=JCCI.JCCo AND JCCM.Contract=JCCI.Contract
JOIN Contracts on JCCM.JCCo=Contracts.JCCo AND JCCM.Contract = Contracts.Contract /**CTE with Contracts filtered by Status**/
JOIN JCDM WITH (NoLock) on JCDM.JCCo=JCCI.JCCo AND JCDM.Department = JCCI.Department
JOIN HQCO WITH (NOLOCK) on HQCO.HQCo=JCCI.JCCo

--- Project Management ID Info
LEFT JOIN JCJMPM WITH (NOLOCK) ON JCCI.BillGroup =JCJMPM.Job AND JCCI.JCCo = JCJMPM.JCCo --Pull project ID info into report CJO.

--- Revenue     
left join (select JCCo, Contract, Item, BilledAmt=sum(JCIP.BilledAmt),ReceivedAmt=sum(JCIP.ReceivedAmt)
from JCIP
where JCIP.Mth>=@BegMth and JCIP.Mth<=@ThroughMth
and (JCIP.ContractAmt<>0 or JCIP.BilledAmt<>0 or JCIP.ReceivedAmt<>0)
group by JCCo, Contract, Item) 
as JCIP on JCIP.JCCo=JCCI.JCCo and JCIP.Contract=JCCI.Contract and JCIP.Item=JCCI.Item

-- Cost
left join (select JCJP.JCCo, JCJP.Contract, JCJP.Item,
ACost1=sum(case when CostType=1 and JCCP.Mth>=@BegMth then JCCP.ActualCost else 0 end),
ACost2=sum(case when CostType=2 and JCCP.Mth>=@BegMth then JCCP.ActualCost else 0 end),
ACost3=sum(case when CostType=3 and JCCP.Mth>=@BegMth then JCCP.ActualCost else 0 end),
ACost4=sum(case when CostType=4 and JCCP.Mth>=@BegMth then JCCP.ActualCost else 0 end),
ACost5=sum(case when CostType=5 and JCCP.Mth>=@BegMth then JCCP.ActualCost else 0 end),
ACost6=sum(case when CostType=6 and JCCP.Mth>=@BegMth then JCCP.ActualCost else 0 end),
ACost7=sum(case when CostType=7 and JCCP.Mth>=@BegMth then JCCP.ActualCost else 0 end),
ACost8=sum(case when CostType=99 and JCCP.Mth>=@BegMth then JCCP.ActualCost else 0 end),
ACost9=sum(case when (CostType>7 and CostType <99) and JCCP.Mth>=@BegMth then JCCP.ActualCost else 0 end),
ActualCost=sum(case when JCCP.Mth>=@BegMth then ActualCost else 0 end) - sum(case when CostType=99 and JCCP.Mth>=@BegMth then JCCP.ActualCost else 0 end)
from JCCP 
join JCJP WITH (NOLOCK) on JCJP.JCCo=JCCP.JCCo and JCJP.Job=JCCP.Job and JCJP.PhaseGroup=JCCP.PhaseGroup
 and JCJP.Phase=JCCP.Phase
where JCCP.Mth>=@BegMth and JCCP.Mth<=@ThroughMth
and JCJP.JCCo=@JCCo and JCJP.Contract>=@BeginContract and JCJP.Contract<=@EndContract
group by JCJP.JCCo, JCJP.Contract, JCJP.Item) 
as JCCP on JCCP.JCCo=JCCI.JCCo and JCCP.Contract=JCCI.Contract and JCCP.Item=JCCI.Item

where JCCI.JCCo=@JCCo and JCCI.Contract>=@BeginContract and JCCI.Contract<=@EndContract
and JCCI.Department=@OHDept

case where @OHDept="15" then "16 else 0

order by JCCI.JCCo, JCCI.Department, JCCI.Contract

2 个答案:

答案 0 :(得分:1)

我没有看到您发布的代码@OHDept中的任何值被赋予了任何值。

无论在何处为其分配值,您都可以使用以下内容来遵循该语句:

set @OHDept = case when @OHDept = '15' then '16' else @OHDept end;

答案 1 :(得分:0)

您似乎试图以类似于您在程序语言中使用case的方式使用if。在SQL中,case是一个表达式,在流中计算为而不是分支

将值15转换为16而将其他值保持不变的表达式为:

case where @OHDept = '15' then '16' else @OhDept end

听起来这个表达式属于select子句,因为你提到过它。

我也认为布尔逻辑正在绊倒你。您可以通过这种方式轻松压缩查询顶部的大量内容。由于and的优先级高于or,因此您不必严格需要括号。

(
    @Status in ('O', 'S') and ContractStatus in (1, 2, 3))
    and MonthClosed > @ThroughMth 
)
or
(
    @Status = 'C' and ContractStatus = 3
    and MonthClosed between @BegMthClosed and @EndMthClosed 
)
or
(
    @Status = 'A' and ContractStatus <> 0
)