Reputation: 21
I am using Case
statement in the Where
condition. When I am trying to use this condition I am getting the results
AND ( XF.SRC_KEY NOT IN (3, 17)
OR UPPER(PM.TRADE_NAME) NOT IN CASE WHEN XF.SRC_KEY = 3 THEN ('AVONEX') END;
But when I tried to extend the case statement I am getting Syntax error as Missing Right Parenthesis
.
AND ( XF.SRC_KEY NOT IN (3, 17)
OR UPPER(PM.TRADE_NAME) NOT IN CASE WHEN XF.SRC_KEY = 3 THEN ('AVONEX')
WHEN XF.SRC_KEY = 17 THEN ('AVONEX','TECFIDERA') END;
Please find the Entire Query for reference :
SELECT x.*
FROM ods_ims_1 x,
ods_lh_ims_2 xf,
ods_prod_master pm,
lh_ods.ods_week_time_dimn t
WHERE x.ims_spp_key = xf.ims_supplier_id (+)
AND x.ndc_no = pm.ndc_no (+)
AND (xf.src_key NOT IN (3, 17)
OR UPPER(pm.trade_name) NOT IN CASE WHEN XF.SRC_KEY = 3 THEN ('AVONEX') END
--WHEN XF.SRC_KEY = 17 THEN ('AVONEX','TECFIDERA') END
OR TRUNC(MONTH_END_DT) >= CASE WHEN XF.SRC_KEY = 3 THEN '31-OCT-14' ELSE '31-JAN-13' END)
AND t.week_time_dimn_key = x.week_time_dimn_key;
Upvotes: 0
Views: 71
Reputation: 12485
I am surprised that the first condition works, but the second doesn't. The first
AND ( XF.SRC_KEY NOT IN (3, 17)
OR UPPER(PM.TRADE_NAME) NOT IN CASE WHEN XF.SRC_KEY = 3 THEN ('AVONEX') END;
is clearly missing a right parenthesis, as is the second:
AND ( XF.SRC_KEY NOT IN (3, 17)
OR UPPER(PM.TRADE_NAME) NOT IN CASE WHEN XF.SRC_KEY = 3 THEN ('AVONEX')
WHEN XF.SRC_KEY = 17 THEN ('AVONEX','TECFIDERA') END;
In each case the missing parenthesis could be placed after the END
of the CASE
.
That said, I'm not sure this syntax would work even with the missing parenthesis. In fact, I am pretty sure it would not. It would be better to write the condition this way, I think:
AND ( XF.SRC_KEY NOT IN (3, 17)
OR XF.SRC_KEY = 3 AND UPPER(PM.TRADE_NAME) != 'AVONEX'
OR XF.SRC_KEY = 17 AND UPPER(PM.TRADE_NAME) NOT IN ('AVONEX','TECFIDERA') ); -- note closing parenthesis
If you're wedded to using a CASE
statement then you can achieve what you're trying to do using REGEXP_LIKE()
:
AND ( XF.SRC_KEY NOT IN (3,17)
OR REGEXP_LIKE(UPPER(PM.TRADE_NAME), CASE WHEN XF.SRC_KEY = 3 THEN '^AVONEX$' WHEN XF.SRC_KEY = 17 THEN '^AVONEX|TECFIDERA$') END );
-- but that's a bit klunky and esoteric, wouldn't you say?
Upvotes: 0
Reputation: 34784
You should avoid using deprecated JOIN
syntax, updating to explicit JOIN
syntax clears up the WHERE
criteria, then you can clean up your WHERE
criteria by getting rid of the CASE
expression when it requires multiple outputs, as it causes the problem you noticed. I believe this should work:
SELECT X.*
FROM ODS_IMS_1 X
LEFT JOIN ODS_LH_IMS_2 XF
ON X.IMS_SPP_KEY = XF.IMS_SUPPLIER_ID
LEFT JOIN ODS_PROD_MASTER PM
ON X.NDC_NO = PM.NDC_NO
JOIN LH_ODS.ODS_WEEK_TIME_DIMN T
ON T.WEEK_TIME_DIMN_KEY = X.WEEK_TIME_DIMN_KEY
WHERE XF.SRC_KEY NOT IN (3, 17)
OR (XF.SRC_KEY = 3 AND UPPER(PM.TRADE_NAME) <> 'AVONEX')
OR (XF.SRC_KEY = 17 AND UPPER(PM.TRADE_NAME) NOT IN ('AVONEX','TECFIDERA'))
OR TRUNC(MONTH_END_DT) >= CASE WHEN XF.SRC_KEY = 3 THEN '31-OCT-14' ELSE '31-JAN-13' END
Note: If I messed up the JOIN
conversion in some way, you can still get your criteria to work with:
SELECT X.*
FROM ODS_IMS_1 X, ODS_LH_IMS_2 XF, ODS_PROD_MASTER PM, LH_ODS.ODS_WEEK_TIME_DIMN T
WHERE X.IMS_SPP_KEY = XF.IMS_SUPPLIER_ID(+)
AND X.NDC_NO = PM.NDC_NO(+)
AND ( XF.SRC_KEY NOT IN (3, 17)
OR (XF.SRC_KEY = 3 AND UPPER(PM.TRADE_NAME) NOT IN ('AVONEX'))
OR (XF.SRC_KEY = 17 AND UPPER(PM.TRADE_NAME) NOT IN ('AVONEX','TECFIDERA'))
OR TRUNC(MONTH_END_DT) >= CASE WHEN XF.SRC_KEY = 3 THEN '31-OCT-14' ELSE '31-JAN-13' END
)
AND T.WEEK_TIME_DIMN_KEY = X.WEEK_TIME_DIMN_KEY;
Upvotes: 1