Can i use case expressions on both sides of the where clause? - sql

Like this
SELECT *
FROM UsersMedicalSurgicalHistory UMSH INNER JOIN CCDTransaction CT on
UMSH.SurgicalHistoryId = CT.RowId
WHERE (
(CASE
WHEN LEN(UMSH.DateOfProcedure)<=4 THEN UMSH.DateOfProcedure
WHEN LEN(UMSH.DateOfProcedure)=0 THEN UMSH.DateOfProcedure
END
=
CASE WHEN #CodeFilter3 IS not null THEN #CodeFilter3
ELSE UMSH.DateOfProcedure end)
OR
(CASE
WHEN LEN(UMSH.DateOfProcedure)>4 THEN
CONVERT(datetime,UMSH.DateOfProcedure,101)
ELSE GETDATE()
END
=
CASE WHEN #CodeFilter2 IS not null THEN #CodeFilter2
ELSE GETDATE()
END)
)
So the question is like CASE expression can be used on both side of WHERE clause

As per your query is written above...
CASES can be minimized to nested conditions as,
SELECT * FROM UsersMedicalSurgicalHistory UMSH
INNER JOIN CCDTransaction CT on UMSH.SurgicalHistoryId = CT.RowId
WHERE (
(UMSH.DateOfProcedure = #CodeFilter3 and #CodeFilter3 IS not null)
OR
#CodeFilter3 IS null
)
OR
(
(
(LEN(UMSH.DateOfProcedure)>4 AND CONVERT(datetime,UMSH.DateOfProcedure,101)=#CodeFilter2)
OR
(LEN(UMSH.DateOfProcedure)<=4 AND GETDATE() =#CodeFilter2)
AND #CodeFilter2 IS NOT NULL
)
OR
(LEN(UMSH.DateOfProcedure)<=4 AND #CodeFilter2 IS null)
)
Try this query... hope it gives desired output :)

Related

Case statement in multiple conditions?

I want to check the column mr.name, if mr.name is null then i have to replace mr.name as mr.ticket_no. How? Can use if else or case?
select ROW_NUMBER() OVER(ORDER BY mr_user) sl_no,* from (select
mr.name as mr_no,
coalesce(mr.user_id,0) as mr_user
from stock_production_lot lot
left join kg_grn grn on (grn.name = lot.grn_no)
left join kg_department_indent mr on (mr.name = grn.mr_no)
order by mr.user_id) main
where mr_user=65
When i use like this
case when mr.name is null then '' else mr.ticket_no = grn.mr_no as mr_no
it will throw an error
if mr.name = null means i have to replace mr.name = mr.ticket_no. I want to check the column mr.name, if mr.name is null then i have to replace mr.name as mr.ticket_no
You can use coalesce() to replace null with anything:
select ROW_NUMBER() OVER(ORDER BY mr_user) sl_no,* from (select
coalesce(mr.name,mr.ticket_no) as mr_no,
coalesce(mr.user_id,0) as mr_user
from stock_production_lot lot
left join kg_grn grn on (grn.name = lot.grn_no)
left join kg_department_indent mr on (mr.name = grn.mr_no)
order by mr.user_id) main
where mr_user=65
But if you are comfortable with case when then use as below:
select ROW_NUMBER() OVER(ORDER BY mr_user) sl_no,* from (select
(case when mr.name is null then mr.ticket_no else mr.name end) as mr_no,
coalesce(mr.user_id,0) as mr_user
from stock_production_lot lot
left join kg_grn grn on (grn.name = lot.grn_no)
left join kg_department_indent mr on (mr.name = grn.mr_no)
order by mr.user_id) main
where mr_user=65

Case Statement within in Statement in MS SQL

I want to compare two different tables in IN statement based on condition.
SELECT DISTINCT
cts.ContactType
,ISNULL(ctl.[Description], CONCAT('Unknown Contact Type: ',cts.ContactType)) AS [Description]
FROM
( SELECT Null AS [ContactType]
WHERE ISNULL(Null, '') <> ''
UNION ALL
SELECT DISTINCT cta.ContactType
FROM
(SELECT u.AccessUserID
FROM v2010_vUsers u
WHERE u.UserID = 'harry_1#cared_t'
UNION ALL
SELECT ur.AccessUserID
FROM v2010_UserRoles ur
WHERE ur.UserID = 'harry_1#cared_t') r --Roles user has
INNER JOIN v2010_UDV_ContactType_AccessMatrix_Full cta --ContactTypes Accessible
ON cta.AccessUserID = r.AccessUserID) cts --ContactTypes Selectable
LEFT JOIN v2010_ListEntries ctl --ContactType List
ON ctl.ListId='CONTACTTYPE' and ctl.Code = cts.ContactType
WHERE cts.ContactType In
(
CASE WHEN (SELECT dbo.f2010_IsFeatureAllowedInTenancy('ContactTypeSC', dbo.f2010_PartnerDivisionID('06b30841-2496-48ef-b91a-21f06a9299f2'))) = '1'
THEN (SELECT Code From v2010_ListEntries WHERE ListId='CONTACTTYPESC')
ELSE (SELECT Code From v2010_ListEntries WHERE ListId='CONTACTTYPE')
END
)
ERROR : Subquery returned more than 1 value. This is not permitted
when the subquery follows =, !=, <, <= , >, >= or when the subquery is
used as an expression.
Error is in following lines:
WHERE cts.ContactType In
(
CASE WHEN (SELECT dbo.f2010_IsFeatureAllowedInTenancy('ContactTypeSC', dbo.f2010_PartnerDivisionID('06b30841-2496-48ef-b91a-21f06a9299f2'))) = '1'
THEN (SELECT Code From v2010_ListEntries WHERE ListId='CONTACTTYPESC')
ELSE (SELECT Code From v2010_ListEntries WHERE ListId='CONTACTTYPE')
END
)
I am not able to use case when in IN statement. if I write WHERE cts.ContactType In (SELECT Code From v2010_ListEntries WHERE ListId='CONTACTTYPESC') it is working but I want to compare condition and based on condition compare table.
It is a bit hard to tell where the multiple rows problem is coming from, but I am thinking:
WHERE (dbo.f2010_IsFeatureAllowedInTenancy('ContactTypeSC', dbo.f2010_PartnerDivisionID('06b30841-2496-48ef-b91a-21f06a9299f2')) = '1' and
cts.ContactType In (SELECT Code From v2010_ListEntries WHERE ListId = 'CONTACTTYPESC')
) OR
(dbo.f2010_IsFeatureAllowedInTenancy('ContactTypeSC', dbo.f2010_PartnerDivisionID('06b30841-2496-48ef-b91a-21f06a9299f2')) <> '1' and
cts.ContactType In (SELECT Code From v2010_ListEntries WHERE ListId = 'CONTACTTYPE'')
)
Or, more simply as:
cts.ContactType In (SELECT le.Code
FROM v2010_ListEntries le CROSS JOIN
(VALUES (CASE WHEN dbo.f2010_IsFeatureAllowedInTenancy('ContactTypeSC', dbo.f2010_PartnerDivisionID('06b30841-2496-48ef-b91a-21f06a9299f2')) THEN 'CONTACTTYPESC' ELSE 'CONTACTTYPESC' END)) v(listId)
WHERE le.ListId = v.ListId
)

Using a CASE WHEN statement and an IN (SELECT...FROM) subquery

I'm trying to create a temp table and build out different CASE WHEN logic for two different medications. In short I have two columns of interest for these CASE WHEN statements; procedure_code and ndc_code. There are only 3 procedure codes that I need, but there are about 20 different ndc codes. I created a temp.ndcdrug1 temp table with these ndc codes for medication1 and temp.ndcdrug2 for the ndc codes for medication2 instead of listing out each ndc code individually. My query looks like this:
CREATE TABLE temp.flags AS
SELECT DISTINCT a.userid,
CASE WHEN (procedure_code = 'J7170' OR ndc_code in (select ndc_code from temp.ndcdrug1)) THEN 'Y' ELSE 'N' END AS Drug1,
CASE WHEN (procedure_code = 'J7205' OR procedure_code = 'C9136' OR ndc_code in (select ndc_code from temp.ndcdrug2)) THEN 'Y' ELSE 'N' END AS Drug2,
CASE WHEN (procedure_code = 'J7170' AND procedure_code = 'J7205') THEN 'Y' ELSE 'N' END AS Both
FROM table1 a
LEFT JOIN table2 b
ON a.userid = b.userid
WHERE...
AND...
When I run this, it returns: org.apache.spark.sql.AnalysisException: IN/EXISTS predicate sub-queries can only be used in a Filter.
I could list these ndc_code values out individually, but there are a lot of them so wanted a more efficient way of going about this. Is there a way to use a sub select query like this when writing out CASE WHEN's?
Query.
CREATE TABLE temp.flags AS
SELECT DISTINCT a.userid,
CASE WHEN (
procedure_code = 'J7170' OR
(select min('1') from temp.ndcdrug1 m where m.ndc_code = a.ndc_code) = '1'
) THEN 'Y' ELSE 'N' END AS Drug1,
CASE WHEN (
procedure_code = 'J7205' OR
procedure_code = 'C9136' OR
(select min('1') from temp.ndcdrug2 m where m.ndc_code = a.ndc_code) = '1'
) THEN 'Y' ELSE 'N' END AS Drug2,
CASE WHEN (procedure_code = 'J7170' AND procedure_code = 'J7205')
THEN 'Y' ELSE 'N' END AS Both
FROM table1 a
LEFT JOIN table2 b
ON a.userid = b.userid
WHERE...
AND...

Combine 3 big tables with 2 joins

I have three tables using complex. I run them separately without problems. Here are the queries:
TABLE A:
select
maxxx.id_demande_diffusion AS ID_DIFFUSION,
maxxx.id_notification as ID_NOTIFICATION,
maxxx.cd_organisation_client as ID_ENTITE,
maxxx.cod_entrep as ID_ENTITE_GARANTE,
maxxx.cd_canal as CD_CANAL,
maxxx.id_demande_diffusion_originale as ID_DIFFUSION_PARENT,
maxxx.ref_maquette as REF_MAQUETTE,
maxxx.qualification_canal as QUALIFICATION_CANAL,
maxxx.ger_id_pli as ID_PLI_GER,
case when maxxx.typ_mvt="S" then 1 else 0 end AS TOP_SUPP,
case when maxxx.typ_mvt = "S" then to_date(substr(maxxx.dt_capt, 1, 11)) else null end AS DT_SUPP,
minnn.typ_mvt as MIN_MVT,
maxxx.typ_mvt as MAX_MVT,
case when minnn.typ_mvt = 'C' then 'C' else 'M' end as TYP_MVT
from
(select s.id_demande_diffusion, s.dt_capt, s.typ_mvt from ${use_database}.pz_send_demande_diffusion as s
join
(select id_demande_diffusion, min(dt_capt) as dtmin from ${use_database}.pz_send_demande_diffusion group by id_demande_diffusion) as minn
on minn.id_demande_diffusion=s.id_demande_diffusion and s.dt_capt=minn.dtmin ) as minnn
join
(select s.id_demande_diffusion, s.typ_mvt, s.id_notification, s.dt_capt, s.cd_organisation_client, s.cod_entrep, s.cd_canal, s.id_demande_diffusion_originale,
s.ref_maquette, s.qualification_canal, s.ger_id_pli from ${use_database}.pz_send_demande_diffusion as s
join
(select id_demande_diffusion, max(dt_capt) as dtmax from ${use_database}.pz_send_demande_diffusion group by id_demande_diffusion) as maxx
on s.id_demande_diffusion=maxx.id_demande_diffusion and s.dt_capt=maxx.dtmax)as maxxx
on minnn.id_demande_diffusion=maxxx.id_demande_diffusion;
TABLE B:
select
maxxx.id_notification as ID_NOTIFICATION,
maxxx.cd_type_destinataire as CD_TYPE_DESTINATAIRE,
case when maxxx.cd_type_destinataire = "IDGRC" then maxxx.destinataire else null end AS ID_PERSONNE,
case when maxxx.cd_type_destinataire = "MAIL" then maxxx.destinataire else null end AS EMAIL_DESTINATAIRE,
case when maxxx.cd_type_destinataire = "SMS" then maxxx.destinataire else null end AS NUM_TEL_DESTINATAIRE,
maxxx.cd_type_evenement,
maxxx.cd_type_notification,
maxxx.cd_type_destinataire_source AS CD_TYPE_DEST_SOURCE,
case when maxxx.cd_type_destinataire_source = "IDGRC" then maxxx.destinataire_source when maxxx.cd_type_destinataire_source = "IDGRC|IDGRC" then substr(maxxx.destinataire_source, 1, locate("|", maxxx.destinataire_source)-1) else null end AS ID_PERS_DEST_SOURCE,
case when maxxx.cd_type_destinataire_source = "SIGMA" or maxxx.cd_type_destinataire_source = "CUBA" then maxxx.destinataire_source else null end AS REF_EXT_DEST_SOURCE,
case when maxxx.cd_type_destinataire_source = "MAIL" then maxxx.destinataire_source else null end AS EMAIL_DEST_SOURCE,
case when maxxx.cd_type_destinataire_source = "SMS" then maxxx.destinataire_source else null end AS NUM_TEL_DEST_SOURCE,
case when maxxx.cd_type_destinataire_source = "IDGRC|IDGRC" then substr(maxxx.destinataire_source, locate("|", maxxx.destinataire_source)+1, length(maxxx.destinataire_source)) end AS ID_PERSONNE_DEST_SOURCE_2
from
(select n.id_notification, n.destinataire, n.cd_type_evenement, n.cd_type_notification, n.destinataire_source, n.cd_type_destinataire, n.cd_type_destinataire_source from ${use_database}.pz_send_notification as n
join
(select id_notification, max(dt_capt) as dtmax from ${use_database}.pz_send_notification group by id_notification) as maxx
on n.id_notification=maxx.id_notification and n.dt_capt=maxx.dtmax) as maxxx;
TABLE C:
select
maxxx.id_communication AS ID_COMMUNICATION,
maxxx.cd_sa as CD_SYS_DIFFUSEUR,
maxxx.type_conteneur as CD_TYPE_CONTENEUR
from
(select n.id_communication, n.cd_sa, n.type_conteneur from ${use_database}.pz_send_comm_retour as n
join
(select id_communication, max(dt_capt) as dtmax from ${use_database}.pz_send_comm_retour group by id_communication) as maxx
on n.id_communication=maxx.id_communication and n.dt_capt=maxx.dtmax) as maxxx;
Is there anyway to combine the three of the using one join and one left join ?
I want o have something like
SELECT * FROM (TABLE A join TABLE B ON A.ID_NOTIFICATION=B.ID_NOTIFICATION) AS TMP LEFT JOIN TABLE C ON TMP.ID_DIFFUSION=C.ID_COMMUNICATION;
I have been trying but it always fails because of missing or misplaced parenthesis.
Thank you!
I have no idea if your queries are correct, but common table expressions (CTE) can frequently be used to keep result set joins clean.
WITH TABLE_A AS
( SELECT
FROM ...
...
),
TABLE_B AS
( SELECT
FROM ...
...
),
TABLE_C AS
( SELECT
FROM ...
...
)
SELECT *
FROM TABLE_A TA
JOIN TABLE_B TB
ON TA.Key_Field = TB.Key_Field
JOIN TABLE_C TC
ON TB.Key_Field = TC.Key_Field

Error cannot generate SQL for Custom SQL at BO

I'm using business object 4 and currently developing a report using custom SQL. Total object and data type selected using custom sql and object at webbi already the same. But when I try to validate webbi always sends error cannot generate sql.
How to fix this and what is the cause of this error?
My sql syntax is as follows:
select * from(
SELECT
DISTINCT
CASE WHEN TRIM(msv26A.PROJECT_NO) IS NULL THEN msvPRJ.PROJECT_NO ELSE msv26A.PROJECT_NO END,
msv660.PROJ_DESC,
msv26A.PO_NO,
msv200.SUPPLIER_NAME,
msv26A.SUPPLIER_NO,
msv260.EXT_INV_NO,
msv200.SUP_TYPEX1,
msv260.CURRENCY_TYPE,
msv000_DC0001.DSTRCT_CODE,
msv000_DC0001.DSTRCT_NAME,
msv260.PMT_STATUS,
msv260.DUE_DATE,
msv260.INV_DATE,
msv260.FOR_INV_ORIG,
msv260.LOC_INV_ORIG,
msv260.FOR_INV_AMD,
msv260.LOC_INV_AMD,
msv260.AMT_RETAINED,
msv260.PRESC_PMT_AMT,
msv260.PP_AMT_LOC,
msv260_1.AMT_PAID_FOR,
msv071.REF_CODE,
CASE WHEN EMV260_AGING_RETENTION.LOC_INV_RETENTION IS NULL THEN 0 ELSE EMV260_AGING_RETENTION.LOC_INV_RETENTION END,
CASE WHEN EMV260_AGING_RETENTION.FOR_INV_RETENTION IS NULL THEN 0 ELSE EMV260_AGING_RETENTION.FOR_INV_RETENTION END
FROM
msv200 RIGHT OUTER JOIN msv26A ON (msv26A.SUPPLIER_NO = msv200.SUPPLIER_NO)
INNER JOIN msv000_DC0001 ON (msv000_DC0001.DSTRCT_CODE = msv26A.DSTRCT_CODE)
INNER JOIN msv260 ON (msv26A.DSTRCT_CODE = msv260.DSTRCT_CODE AND msv26A.SUPPLIER_NO = msv260.SUPPLIER_NO AND msv26A.INV_NO = msv260.INV_NO)
LEFT OUTER JOIN msvPRJ ON (msvPRJ.DSTRCT_CODE = msv26A.DSTRCT_CODE AND TRIM(msvPRJ.PO_NO) = trim(msv26A.PO_NO))
LEFT OUTER JOIN msv660 ON (msv26A.DSTRCT_CODE = msv660.DSTRCT_CODE AND (CASE WHEN TRIM(msv26A.PROJECT_NO) IS NULL
THEN msvPRJ.PROJECT_NO ELSE msv26A.PROJECT_NO END) = msv660.PROJECT_NO)
LEFT OUTER JOIN msv260 msv260_1 ON (msv260_1.DSTRCT_CODE = msv260.DSTRCT_CODE and msv260_1.SUPPLIER_NO = msv260.SUPPLIER_NO and msv260_1.INV_NO = msv260.INV_NO)
LEFT OUTER JOIN msv071 ON (msv071.ENTITY_VALUE=msv260.SUPPLIER_NO AND msv071.ENTITY_TYPE='SUP')
LEFT OUTER JOIN (SELECT A.DSTRCT_CODE,
A.SUPPLIER_NO,
A.ORIG_INV_NO,
SUM(CASE WHEN A.LOC_INV_AMD <> 0
THEN A.LOC_INV_AMD ELSE A.LOC_INV_ORIG END) LOC_INV_RETENTION,
SUM(CASE WHEN A.FOR_INV_AMD <> 0
THEN A.FOR_INV_AMD ELSE A.FOR_INV_ORIG END) FOR_INV_RETENTION
FROM msv260 A
WHERE A.FULL_PER_LOADED <= #prompt('Enter Full Period(From):','A','260\Full Per Loaded',Mono,Free,Persistent,,User :3)
AND TRIM(A.PMT_STATUS) >= '30' AND TRIM(A.PMT_STATUS) <= '55'
GROUP BY
A.DSTRCT_CODE,
A.SUPPLIER_NO,
A.ORIG_INV_NO) EMV260_AGING_RETENTION
ON (msv260.DSTRCT_CODE = EMV260_AGING_RETENTION.DSTRCT_CODE
AND msv260.SUPPLIER_NO = EMV260_AGING_RETENTION.SUPPLIER_NO
AND msv260.INV_NO = EMV260_AGING_RETENTION.ORIG_INV_NO)
WHERE
msv26A.DSTRCT_CODE in #prompt('Enter value(s) for Dstrct Code:','A','msv26a\Dstrct Code',Multi,Free,Persistent,,User:5)
AND
TRIM(msv260.PMT_STATUS) >= '30' AND TRIM(msv260.PMT_STATUS) <= '55'
AND
(
( msv260.FULL_PER_LOADED <= #prompt('Enter Full Period(From):','A','260\Full Per Loaded',Mono,Free,Persistent,,User :3)
AND msv260.FULL_PER_PAID = '000000' )
OR
( msv260.FULL_PER_PAID > #prompt('Enter Full Period(To):','A','260\Full Per Paid',Mono,Free,Persistent,,User :4)
AND msv260.FULL_PER_LOADED <= #prompt('Enter Full Period(From):','A','260\Full Per Loaded',Mono,Free,Persistent,,User :3) )
)
AND msv260.CURRENCY_TYPE <> ' '
ORDER BY msv000_DC0001.DSTRCT_CODE, msv260.SUPPLIER_NO, msv200.SUP_TYPEX1, msv260.CURRENCY_TYPE)
WHERE (DSTRCT_CODE,SUPPLIER_NO,EXT_INV_NO) IN (SELECT
DISTINCT DSTRCT_CODE,SUPPLIER_NO,EXT_INV_NO FROM msv900
WHERE DSTRCT_CODE in #prompt('Enter value(s) for Dstrct Code:','A','msv900\Dstrct Code',Multi,Free,Persistent,,User:1)
AND FULL_PERIOD <= #prompt('Enter Full Period(From):','A','msv900\Full Period',Mono,Free,Persistent,,User :2)
AND ACCOUNT_CODE IN ('21101')
)
ORDER BY
PROJECT_NO,
SUPPLIER_NO