SQL Query Error with CASE Statement? - sql

I'm attempting to run this query using Simba's ODBC SFDC driver but the log shows me an error near the case statement. I'm not totally convinced its an error with the CASE statement but I don't see where my error is. Someone please help!!!!
SELECT
Account_Group__c,
Hospital_Sales_Teammate__c,
Name,
StageName,
CloseDate,
Yr_Credited__c,
Probability,
Census__c,
Credit__c,
Related_VSA__c,
AB_Hospital_Relationship_Type__c,
CASE
WHEN Age_In_Stage__c >0 and Age_In_Stage__c <= 30 THEN '<30'
WHEN Age_In_Stage__c >30 and Age_In_Stage__c <= 60 THEN '31-60'
WHEN Age_In_Stage__c >60 and Age_In_Stage__c <= 90 THEN '61-90'
ELSE '>90' END AS Age_Bucket,
CASE
WHEN (Type = "Existing Business - Renewal" OR Type = 'Existing Business - Amendment')
AND (Account_HHV_Segment__c='A' OR Account_HHV_Segment__c='B')
AND AB_Hospital_Relationship_Type__c<>'N/A'
AND (RecordType='012300000000PWuAAM'
OR RecordType='01250000000DcJkAAK'
OR RecordType='01250000000DpV4AAK'
OR RecordType='01250000000Dxd7AAC'
OR RecordType='01250000000DoFPAA0'
OR RecordType='01250000000DuuEAAS') THEN 'Hosp'
WHEN Name LIKE '%AB Hospital Loss%' THEN 'Hosp'
ELSE '' END AS Hospital_Eligible,
CASE
WHEN RecordType='01250000000DpV4AAK'
AND Type LIKE '%Acquisition%'
THEN 'Acq'
ELSE '' END AS Acquisition_Eligible,
CASE
WHEN RecordType='01250000000Dxd7AAC'
AND (Business_Unit__c="Full Conversion" OR Business_Unit__c="Partial Conversion")
THEN 'BGC'
ELSE '' END AS Conversion_Eligible,
CASE
WHEN RecordType='01250000000DuuEAAS'
AND Type_of_Agreement__c ="MDA" OR Type_of_Agreement__c ="Joinder" OR Type_of_Agreement__c ="JV"
THEN 'Incr Doc'
ELSE '' END AS Incr_Doc_Eligible
FROM
Opportunity
WHERE
Eligible__c<>'No'
AND NOT Name LIKE '%test%'
AND NOT Name LIKE '%Test%'
AND NOT Name LIKE '%TEST%'
ORDER BY
Account_Group__c ASC

Business_Unit__c="Full Conversion" (and other places as well): You are using double quotes instead of single quotes (as you do in the rest of the query). I bet that's the problem...
Also, this is a case expression, not a statement.

Why are you using double quotes?
(Type = "Existing Business - Renewal" OR Type = 'Existing Business - Amendment')
You should change it to
(Type = 'Existing Business - Renewal' OR Type = 'Existing Business - Amendment')

Related

Unable to Correct Oracle Error ORA-00905 Missing Keyword in SQL

I've been grinding on this small snippet of simple code for a day and can't find the issue causing the error. As the title states, I am getting error ORA-00905 Missing Keyword when trying to execute the following code:
SELECT DISTINCT DM.DESCRIPTION AS "AGENCY",
DM.DEPT_NO AS "DEPT NO",
CASE
WHEN VMP.RESERVE_DT IS NULL THEN
NULL
ELSE
VMP.RESERVE_DT
END AS "RESV_DT",
CASE
WHEN VMP.EST_PICKUP_DT IS NULL THEN
NULL
ELSE
VMP.EST_PICKUP_DT
END AS "EST_PKUP_DT",
CASE
WHEN VMP.EST_RETURN_DT IS NULL THEN
NULL
ELSE
VMP.EST_RETURN_DT
END AS "EST_RETN_DT",
VMP.EMP_NAME AS "EMPL_NAME",
VMP.UNIT_NO AS "UNIT_NUMBER",
VMP.RENTAL_CLASS_DESCRIPTION AS "RENT_CLS",
VMP.MP_TICKET_NO AS "MP_TKT_NO"
FROM DEPT_MAIN DM
INNER JOIN VIEW_MPOOL VMP ON VMP.DEPT_ID = DM.DEPT_ID
WHERE CASE
WHEN VMP.EST_PICKUP_DT IS NULL THEN
NULL
ELSE
TRUNC(VMP.EST_PICKUP_DT) = TRUNC(SYSDATE)
END
GROUP BY DM.DESCRIPTION,
DM.DEPT_NO,
CASE
WHEN VMP.RESERVE_DT IS NULL THEN
NULL
ELSE
VMP.RESERVE_DT
END,
CASE
WHEN VMP.EST_PICKUP_DT IS NULL THEN
NULL
ELSE
VMP.EST_PICKUP_DT
END,
CASE
WHEN VMP.EST_RETURN_DT IS NULL THEN
NULL
ELSE
VMP.EST_RETURN_DT
END,
VMP.EMP_NAME,
VMP.UNIT_NO,
VMP.RENTAL_CLASS_DESCRIPTION,
VMP.MP_TICKET_NO
ORDER BY CASE
WHEN VMP.EST_PICKUP_DT IS NULL THEN
NULL
ELSE
VMP.EST_PICKUP_DT
END ASC
The basis of this code was generated through an adhoc reporting program and was originally fully-qualified. I stripped out the extraneous quotation marks and assigned table aliases to clean it up. Though I hoped these efforts would help me find the issue, I am unable to find the cause. Thank you for your consideration.
Try to replace this :
WHERE
CASE
WHEN VMP.EST_PICKUP_DT IS NULL THEN NULL
ELSE TRUNC(VMP.EST_PICKUP_DT) = TRUNC(SYSDATE)
END
With :
WHERE
CASE
WHEN VMP.EST_PICKUP_DT IS NULL THEN NULL
ELSE TRUNC(VMP.EST_PICKUP_DT)
END
= TRUNC(SYSDATE)
Please note that this whole expression (and others similar in the query) could be simplified as as :
WHERE
TRUNC(VMP.EST_PICKUP_DT) = TRUNC(SYSDATE)
When VMP.EST_PICKUP_DT is NULL, TRUNC will return NULL, which will not be equal to TRUNC(SYSDATE).
Here:
WHERE
CASE
WHEN VMP.EST_PICKUP_DT IS NULL
THEN NULL
ELSE TRUNC(VMP.EST_PICKUP_DT) = TRUNC(SYSDATE)
END
The END is after a comparison and the case is not being compared against a value.
Switch it like:
WHERE
CASE
WHEN VMP.EST_PICKUP_DT IS NULL
THEN NULL
ELSE TRUNC(VMP.EST_PICKUP_DT)
END = TRUNC(SYSDATE)
Which as horse says, can just be simplified as
WHERE TRUNC(VMP.EST_PICKUP_DT) = TRUNC(SYSDATE)
since a NULL value on VMP.EST_PICKUP_DT will never match TRUNC(SYSDATE).
can't find the issue causing the error
Although I suppose that #EzLo and #a_horse_with_no_name maybe already found error in this case, I can propose a general procedure in debugging such queries.
Step 1: Debug your JOIN- and WHERE- predicates
Comment everything in your SELECT-statement, leave only JOINs, substitute fields with * or constant expression.
E.g.
SELECT 1
-- DISTINCT DM.DESCRIPTION AS "AGENCY",
-- DM.DEPT_NO AS "DEPT NO",
-- CASE
-- ....
-- VMP.RENTAL_CLASS_DESCRIPTION AS "RENT_CLS",
-- VMP.MP_TICKET_NO AS "MP_TKT_NO"
FROM DEPT_MAIN DM
INNER JOIN VIEW_MPOOL VMP ON VMP.DEPT_ID = DM.DEPT_ID
WHERE CASE
WHEN VMP.EST_PICKUP_DT IS NULL THEN
NULL
ELSE
TRUNC(VMP.EST_PICKUP_DT) = TRUNC(SYSDATE)
END
-- GROUP BY DM.DESCRIPTION,
-- ....
-- ORDER BY ..
In case of multiple complex predicates - uncomment one predicate at a time.
Step 2: Debug your GROUP BYs and HAVINGs
Uncomment GROUP BY section and edit fields section of your query.
If you have complex groupby's - uncomment by one field at time.
Start from simplest to complex
SELECT
DM.DESCRIPTION
,DM.DEPT_NO
-- ...
FROM DEPT_MAIN DM
INNER JOIN VIEW_MPOOL VMP ON VMP.DEPT_ID = DM.DEPT_ID
WHERE CASE
WHEN VMP.EST_PICKUP_DT IS NULL THEN
NULL
ELSE
TRUNC(VMP.EST_PICKUP_DT) = TRUNC(SYSDATE)
END
GROUP BY DM.DESCRIPTION
,DM.DEPT_NO
Copy-paste your GROUP BYs into SELECT fields section.
Step 3: Debug you aggregates, field transformation and renames
Now you have correct SELECT-query but probably not in the shape you want.
Step 4: Debug ORDER BYs
You have correct shape and in last step you need to ORDER BY your data.
If you have decent editor/IDE you can find source of error in 5-10 minutes even in cases of complex queries (and even RDBMS engine bugs)
P.S.
It's better to note which version of RDBMS you are using.

Denodo - Unable to case DATE>= addday(cast(now() as date),-365)

I've encountered an issue when trying to obtain the following output:
"If x_date >= now-365 then 1 else 0"
My select statement reads:
SELECT
id,
x_date,
CASE x_date
WHEN x_date >= addday(cast(now() as date),-365) then 1
else 0
end as output
I'm receiving an error message that reads:
"SQL Error [30100] [HY000]: CASE argument case((xdate,ge,[addday(trunc(cast('date', now(), 'DATE')) '-365')], utc_il8n), 'true', 'false') is not compatible with the rest of the values.
Has anyone else performed a similar operation with dates in a CASE statement? The Addday works fine and returns 2017-01-05.
Issue with the CASE syntax. I think reading this and other sources may have cause the confusion: https://www.techonthenet.com/sql_server/functions/case.php
Should read:
SELECT
id,
x_date,
CASE WHEN x_date >= addday(cast(now() as date),-365) then 1
else 0
end as output

Case select another column AS400 query

I have simple query which is not working:
SELECT BATCH_0002.CREATOR, BATCH_0002.GLEXR,
case when BATCH_0002.GLIVD >'0' THEN BATCH_0002.GLIVD ELSE BATCH_0002.date end
as tarih FROM BATCH_0002
Error is:
ERROR: [IBM][System i Access ODBC Driver][DB2 for i5/OS]SQL0581 - The
results in a CASE expression are not compatible. Error Code:
-581
but when I change column name to something different than GLIVD, it is working.
SELECT BATCH_0002.CREATOR, BATCH_0002.GLEXR,
case when BATCH_0002.GLIVD >'0' THEN BATCH_0002.GLEXR ELSE BATCH_0002.date end
as tarih FROM BATCH_0002
Is there something wrong with my case statement?
In Case statement result datatype should be same. Here Using int and date as result in case that's why error showing for incompatible data
you should cast one datatype to another
SELECT BATCH_0002.CREATOR, BATCH_0002.GLEXR, case when BATCH_0002.GLIVD >'0' THEN cast(BATCH_0002.GLIVD as char) ELSE cast(BATCH_0002.date as char) end as tarih FROM BATCH_0002
thank you for all answers regarding data types. worked on this information and now solved, this works very well:
SELECT BATCH_0002.CREATOR, BATCH_0002.GLEXR,
case when BATCH_0002.GLIVD >'0' THEN
DATE(CHAR(1900000 + BATCH_0002.GLIVD))
ELSE BATCH_0002.date end as tarih FROM BATCH_0002

Using CASE statement name as another reference filed in another CASE statement

Is it possible to refer to another case statement name in another case statement within SQL query?
Example: I have 3 case statements. The first 2 case statements are returning values based off coded fields. My 3rd case statement I would like to refer to the ending case name to return a sum of quantity.
However, I cannot figure how to get the case statement to refer to the previous case names I created. I hope I am explaining this correctly.
Any assistance would be greatly appreciated. Please see attached image for more detail.
SELECT CI_ITEM.ITEMCODE
, CI_ITEM.ITEMCODEDESC
, CASE WHEN DATEDIFF("M",CI_ITEM.DATECREATED,GETDATE()) <60 THEN DATEDIFF("M",CI_ITEM.DATECREATED,GETDATE())
ELSE 60 END AS NO_OF_MONTHS
, CASE WHEN DATEDIFF("M",IM_ITEMTRANSACTIONHISTORY.TRANSACTIONDATE,GETDATE()) <=60
AND IM_ITEMTRANSACTIONHISTORY.TRANSACTIONCODE IN ('BI','II','SO','WI')
THEN IM_ITEMTRANSACTIONHISTORY.TRANSACTIONQTY *-1 ELSE '0' END AS QTY_CONSUMED_60_MONTHS
, CASE WHEN NO_OF_MONTHS = 0 THEN 0 ELSE SUM([QTY_CONSUMED_60_MONTHS])/ [NO_OF_MONTHS] END AS MONTHLY_AVE_ON_60MONTHS_DATA
FROM CI_ITEM
INNER JOIN IM_ITEMTRANSACTIONHISTORY ON CI_ITEM.ITEMCODE = IM_ITEMTRANSACTIONHISTORY.ITEMCODE
Simply wrap your dependent cases within a sub query and reference them as fields of the sub query result.
SELECT
*,
CASE WHEN NO_OF_MONTHS = 0 THEN 0 ELSE SUM([QTY_CONSUMED_60_MONTHS])/ [NO_OF_MONTHS] END AS MONTHLY_AVE_ON_60MONTHS_DATA
FROM
(
SELECT CI_ITEM.ITEMCODE
, CI_ITEM.ITEMCODEDESC
, CASE WHEN DATEDIFF("M",CI_ITEM.DATECREATED,GETDATE()) <60 THEN DATEDIFF("M",CI_ITEM.DATECREATED,GETDATE())
ELSE 60 END AS NO_OF_MONTHS
, CASE WHEN DATEDIFF("M",IM_ITEMTRANSACTIONHISTORY.TRANSACTIONDATE,GETDATE()) <=60
AND IM_ITEMTRANSACTIONHISTORY.TRANSACTIONCODE IN ('BI','II','SO','WI')
THEN IM_ITEMTRANSACTIONHISTORY.TRANSACTIONQTY *-1 ELSE '0' END AS QTY_CONSUMED_60_MONTHS
FROM CI_ITEM
INNER JOIN IM_ITEMTRANSACTIONHISTORY ON CI_ITEM.ITEMCODE = IM_ITEMTRANSACTIONHISTORY.ITEMCODE
)AS X

Get work time in minutes based on shift schedule

In production we have 3 shifts. Each Shift timing is described in table tbl_ShiftSched:
WT - work time, PT - break time.
ShiftTmID - schedule for 2 and for 3 shifts.
I am looking for easy way to get work time in minutes having start and end time.
For example, having input between #2015.05.29 06:10:00# and #2015.05.29 09:30:00# and tbl_WorkStations.WksID='GRD' (Workstation code with relation on ShiftTmID ='3P') should give output 190 min.
I have function in MS Access which gives me needed output. But when migrated to T-SQL it becomes very complicated because I do not find easy way how to use alias in T-SQL. Here is the code:
USE [STRDAT]
GO
declare
#strWks varchar(3),
#dteIN datetime='2013.08.05 03:30',
#dteOUT datetime='2013.08.05 05:30',
#strShf varchar(12)=null,--'2013.08.04-3',
#strInd varchar(2) = 'WT',
#dteFTm datetime,
#dteShf date
--#PrdS datetime,
--#PrdE datetime
select top 1
#dteFTm =
case
when #strShf is not null
then (select shiftstart from tbl_ShiftSched where ShiftTmID=(select ShiftTiming from tbl_WorkStations where WksID=#strWks) and shift=right(#strshf,1) and sortind=1)
else #dteIN-dateadd(day,datediff(day,0,#dteIN),0) --CAST(#dteIN-cast(floor(#dteIN) as float) as datetime)
end,
#dteShf=
case
when #strShf is not null
then left(#strShf,10)
else convert(varchar,dateadd(day,datediff(day,0,#dteIN),0),102)
end
--select #dteftm,#dteShf
SELECT tbl_ShiftSched.Shift,
tbl_ShiftSched.SortInd,
[ShiftStart]+
case
when #dteFTm>[shiftstart]
then DateAdd(day,1,#dteShf)
else #dteShf
end AS PrdS,
[ShiftEnd]+
case
when #dteFTm>[shiftend]
then DateAdd(day,1,#dteShf)
else #dteShf
end AS PrdE,
case
when #dteIN>=[PrdS] AND [PrdE]>=#dteOUT
then DateDiff(minute,#dteIN,#dteOUT)
else case
when #dteIN<=[PrdS] AND [PrdE]<=#dteOUT
then DateDiff(minute,[PrdS],[PrdE])
else case
when [PrdS]<=#dteIN AND #dteIN<=[PrdE]
then DateDiff(minute,#dteIN,[Prde])
else case
when [PrdS]<=#dteOUT AND #dteOUT<=[PrdE]
then DateDiff(minute,[Prds],#dteOUT)
else 0
end
end
end
end AS Tm,
#dteIN AS S,
#dteOUT AS E,
tbl_ShiftSched.ShiftType,tbl_ShiftSched.ShiftStart,tbl_ShiftSched.ShiftEnd
FROM tbl_WorkStations
INNER JOIN tbl_ShiftSched ON tbl_WorkStations.ShiftTiming = tbl_ShiftSched.ShiftTmID
WHERE (((tbl_WorkStations.WksID)=#strWks))
Off course it gives me an error Invalid column name 'PrdS' and 'PrdE' because I use alias.
Must be some more easy way to achieve it. Maybe I am on wrong direction?...
Whenever I have to calculate a field and use the results in a second field, I use a common table expression to make the first calculation. Given this query, it could look like this:
with cte_preprocess as
(
SELECT tbl_ShiftSched.Shift,
tbl_ShiftSched.SortInd,
[ShiftStart]+
case
when #dteFTm>[shiftstart]
then DateAdd(day,1,#dteShf)
else #dteShf
end AS PrdS,
[ShiftEnd]+
case
when #dteFTm>[shiftend]
then DateAdd(day,1,#dteShf)
else #dteShf
end AS PrdE,
tbl_ShiftSched.ShiftType,tbl_ShiftSched.ShiftStart,tbl_ShiftSched.ShiftEnd
FROM tbl_WorkStations
INNER JOIN tbl_ShiftSched ON tbl_WorkStations.ShiftTiming = tbl_ShiftSched.ShiftTmID
WHERE (((tbl_WorkStations.WksID)=#strWks))
)
SELECT [Shift]
, SortInd
, PrdS
, PrdE
, case
when #dteIN>=[PrdS] AND [PrdE]>=#dteOUT
then DateDiff(minute,#dteIN,#dteOUT)
else case
when #dteIN<=[PrdS] AND [PrdE]<=#dteOUT
then DateDiff(minute,[PrdS],[PrdE])
else case
when [PrdS]<=#dteIN AND #dteIN<=[PrdE]
then DateDiff(minute,#dteIN,[Prde])
else case
when [PrdS]<=#dteOUT AND #dteOUT<=[PrdE]
then DateDiff(minute,[Prds],#dteOUT)
else 0
end
end
end
end AS Tm
, #dteIN
, #dteOUT
, ShiftEnd
FROM cte_preprocess
More on CTE's here