TSQL IN and NOT IN - tsql

I have the below query that returns all diagnosis that do not have a '-829' value associated to them. The query does work but I think that I've made it harder than it should be. Is there a tidier way of doing this?
select distinct
c2.diagnosisn DiagnosisName,
a2.text CareLookup
from core_patdiagnosis c1
LEFT OUTER JOIN core_diagnosis c2 ON c1.diagnosis = c2.id
LEFT OUTER JOIN core_carecontext c3 ON c1.carecontex = c3.id
LEFT OUTER JOIN applookup_instance a1 ON c1.lkp_specialty = a1.id
LEFT OUTER JOIN core_diagnosis_taxonomyma c5 ON c2.id = c5.id
LEFT OUTER JOIN applookup_instance a3 ON c5.lkp_taxonomyna = a3.id
LEFT OUTER JOIN applookup_instance a2 ON c3.lkp_context = a2.id
where c2.id IN
(
select c11.id core_diagnosis_c1_id
from core_diagnosis c11
LEFT OUTER JOIN core_diagnosis_taxonomyma c21 ON c11.id = c21.id
LEFT OUTER JOIN applookup_instance a11 ON c21.lkp_taxonomyna = a11.id
WHERE
c11.isactive = 1
and a11.id != -829 or a11.id is null
)
AND
c2.id NOT IN
(
select c12.id ProcID
from core_procedure c12
LEFT OUTER JOIN core_procedure_taxonomyma c22 ON c12.id = c22.id
LEFT OUTER JOIN applookup_instance a12 ON c22.lkp_taxonomyna = a12.id
WHERE
c12.isactive = 1
and a12.id = -829 or a12.id is null
)
AND
c1.sys_creation_datetime > '01 Dec 2017 00:00:00' AND a2.text like
'%Emergency%'

extra stuff not used
a2.text like '%Emergency%' breaks the outer join
select distinct c2.diagnosisn DiagnosisName, a2.text CareLookup
from core_patdiagnosis c1
JOIN core_diagnosis c2 ON c2.id = c1.diagnosis
JOIN core_carecontext c3 ON c3.id = c1.carecontex
JOIN applookup_instance a2 ON a2.id = c3.lkp_context
where c2.id IN
( select c11.id
from core_diagnosis c11
LEFT OUTER JOIN core_diagnosis_taxonomyma c21 ON c11.id = c21.id
LEFT OUTER JOIN applookup_instance a11 ON c21.lkp_taxonomyna = a11.id
WHERE c11.isactive = 1 and a11.id != -829
or a11.id is null
)
AND
c2.id NOT IN
( select c12.id
from core_procedure c12
LEFT OUTER JOIN core_procedure_taxonomyma c22 ON c12.id = c22.id
LEFT OUTER JOIN applookup_instance a12 ON c22.lkp_taxonomyna = a12.id
WHERE c12.isactive = 1 and a12.id = -829
or a12.id is null
)
AND c1.sys_creation_datetime > '01 Dec 2017 00:00:00'
AND a2.text like '%Emergency%'

You could use a CTE (Common Table Expression - see msdn page):
WITH BufferTableCTE (id)
AS
(...)
SELECT ...
FROM ...
WHERE id in (SELECT id FROM BufferTableCTE WHERE id != -829)
AND NOT id in (SELECT id FROM BufferTableCTE WHERE id = -829)
AND ...
Another way would be to store an intermediate result in a temporary table and then use this temporary table later on (twice, once with id != -829 and once with id = 829)
Both ways would reduce your repeated sql declarations.

Related

Postgresql: UNION ALL on two queries using "with <name> as"?

I have this query:
with active_cars as (
select c.id
from car c
inner join dealership d on c.dealer_id = d.id and d.active=true and d.ownerId=${userId}
)
select cd.*
from car_details cd
inner join active_cars ac on cd.car_id = ac.id
where cd.ratings=5;
Then I have query:
with ports_active_cars as (
select c.id
from car c
inner join ports p on c.port_id = p.id and p.active=true and p.ownerId=${userId}
)
select cd.*
from car_details cd
inner join ports_active_cars pac on cd.car_id = pac.id
I'd like to know how I can combine the result of the two queries into one, so I get one result including all car_details records.
I tried this:
with active_cars as (
select c.id
from car c
inner join dealership d on c.dealer_id = d.id and d.active=true and d.ownerId=${userId}
)
select cd.*
from car_details cd
inner join active_cars ac on cd.car_id = ac.id
where cd.ratings=5
union all
with ports_active_cars as (
select c.id
from car c
inner join ports p on c.port_id = p.id and p.active=true and p.ownerId=${userId}
)
select cd.*
from car_details cd
inner join ports_active_cars pac on cd.car_id = pac.id;
but that is wrong, does not run.
Is there a way to combine the two into one result returning all rows of car_details?
You need to define both CTEs at the start of the statement:
with active_cars as (
select c.id
from car c
inner join dealership d
on c.dealer_id = d.id and d.active = true and d.ownerId = ${userId}
),
ports_active_cars as (
select c.id
from car c
inner join ports p
on c.port_id = p.id and p.active=true and p.ownerId = ${userId}
)
select cd.*
from car_details cd
inner join active_cars ac on cd.car_id = ac.id
where cd.ratings = 5
union all
select cd.*
from car_details cd
inner join ports_active_cars pac on cd.car_id = pac.id;

Jasper Report: error executing SQL statement by Collection Parameter

I'm creating a report which's passing by collection parameter.
The parameter name as 'ids' and the class is java.util.Collection.
My query:
select * from order_deliveryorder a
left join order_deliveryorderline b on a.id = b.d_order_id
left join order_item c on c.id = b.product_id
left join order_orderline e on e.id = b.s_order_id
left join order_order f on e.order_id = f.id
left join order_itemsection g on g.id = f.section_id
left join order_location d on d.id = a.location_id
left join order_location h on h.id = a.from_location_id
where a.id in ('2377900603251741014','2377900603251740997','2377900603251740967')
the query in jasper:
select * from order_deliveryorder a
left join order_deliveryorderline b on a.id = b.d_order_id
left join order_item c on c.id = b.product_id
left join order_orderline e on e.id = b.s_order_id
left join order_order f on e.order_id = f.id
left join order_itemsection g on g.id = f.section_id
left join order_location d on d.id = a.location_id
left join order_location h on h.id = a.from_location_id
where $X{IN, a.id, ids}
The value of parameter "ids" is ["2377900603251741014","2377900603251740997","2377900603251740967"]
In the End, had met the error executing sql statement.

Order dates with multiple columns (some containing nulls)

I have 4 dates (derived from separate subqueries) as in below but I want to find the MAX and MIN dates of the values returned.
I've tried using CASE which will not work with the null values.
Also tried using COALESCE in the subs to get values and then using CTE but this also didn't work.
(The overall query is to find customers with no -9 in a1.id)
There's a lot of help in SO but nothing that I can get to fit this purpose.
Any help would be greatly appreciated.
DESIRED COLUMNS
PAT_ID Date1 Date2 Date3 Date4 MAX MIN
1 01/04/2015 25/12/2000 02/02/2011 01/04/2015 25/12/2000
2 05/08/1950 11/11/2011 11/11/2011 05/08/1950
3 04/01/1958 04/01/1958 04/01/1958
4 01/01/1900 01/01/1900
5 15/08/2017 07/07/1967 15/08/2017 07/07/1967
select distinct
ca1.id AS PT_ID,
(select Top 1 s1z.appointmen ApptDate
from schl_booking_appoin s1z
LEFT OUTER JOIN core_patient c3z ON s1z.patient = c3z.id
LEFT OUTER JOIN schl_appt_history_s s2z ON s1z.currentsta = s2z.id
LEFT OUTER JOIN applookup_instance a2z ON s2z.lkp_status = a2z.id
where (c3z.id = ca1.id and a2z.text not like '%cancelled%' and s1z.appointmen
> :SYS_DATE_TIME)
order by s1z.appointmen asc ) AS Date1,
(select Top 1
s1q.appointmen ApptDate
from schl_booking_appoin s1q
LEFT OUTER JOIN core_patient c3q ON s1q.patient = c3q.id
LEFT OUTER JOIN schl_appt_history_s s2q ON s1q.currentsta = s2q.id
LEFT OUTER JOIN applookup_instance a2q ON s2q.lkp_status = a2q.id
where (c3q.id = ca1.id and a2q.text not like '%cancelled%' and s1q.appointmen
< :SYS_DATE_TIME)
order by s1q.appointmen desc ) AS Date2,
(select top 1
CONVERT (VARCHAR(20),c2y.admissiond, 103) AdmissionDate
from core_admissiondetai c2y
LEFT OUTER JOIN core_pas_event c3y ON c2y.pasevent = c3y.id
LEFT OUTER JOIN core_patient c4y ON c3y.patient = c4y.id
where (c4y.id = ca1.id)
order by c2y.admissiond desc ) AS Date3,
(select top 1
CONVERT(VARCHAR(20),c5k.arrivaldat,103) ArrivalDate
from core_emergencyatten c5k
LEFT OUTER JOIN core_patient c6k ON c5k.patient = c6k.id
where (c6k.id = ca1.id)
order by c5k.arrivaldat desc ) AS Date4
from core_patient ca1
LEFT OUTER JOIN core_patient_c_identifi ca2 ON ca1.id = ca2.id
LEFT OUTER JOIN applookup_instance aa2 ON ca1.lkp_sex = aa2.id
LEFT OUTER JOIN applookup_instance aa1 ON ca2.lkp_c_ty = aa1.id
LEFT OUTER JOIN applookup_instance ab1 ON ca1.lkp_overseascl = ab1.id
LEFT OUTER JOIN core_organisation cx4 ON ca1.practice = cx4.id
WHERE ca1.id IN
(
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where ((ca2.merged = 0 or ca2.merged is null)
and aa1.id = -2404) )
AND ca1.id NOT IN (
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where (c1.namesurname not like '%XXTEST%'
and c1.namesurname not like '%ZZ%'
and a1.id = -9)
)
try this version. Your old query acts as a subquery and introducing a new column definition to get the Max Date.
SELECT PT_ID,
(
SELECT Max(v)
FROM (VALUES (Date1), (Date2), (Date3),(Date4)) AS value(v)
) as [MaxDate]
FROM
(
select distinct
ca1.id AS PT_ID,
(select Top 1 s1z.appointmen ApptDate
from schl_booking_appoin s1z
LEFT OUTER JOIN core_patient c3z ON s1z.patient = c3z.id
LEFT OUTER JOIN schl_appt_history_s s2z ON s1z.currentsta = s2z.id
LEFT OUTER JOIN applookup_instance a2z ON s2z.lkp_status = a2z.id
where (c3z.id = ca1.id and a2z.text not like '%cancelled%' and s1z.appointmen
> :SYS_DATE_TIME)
order by s1z.appointmen asc ) AS Date1,
(select Top 1
s1q.appointmen ApptDate
from schl_booking_appoin s1q
LEFT OUTER JOIN core_patient c3q ON s1q.patient = c3q.id
LEFT OUTER JOIN schl_appt_history_s s2q ON s1q.currentsta = s2q.id
LEFT OUTER JOIN applookup_instance a2q ON s2q.lkp_status = a2q.id
where (c3q.id = ca1.id and a2q.text not like '%cancelled%' and s1q.appointmen
< :SYS_DATE_TIME)
order by s1q.appointmen desc ) AS Date2,
(select top 1
CONVERT (VARCHAR(20),c2y.admissiond, 103) AdmissionDate
from core_admissiondetai c2y
LEFT OUTER JOIN core_pas_event c3y ON c2y.pasevent = c3y.id
LEFT OUTER JOIN core_patient c4y ON c3y.patient = c4y.id
where (c4y.id = ca1.id)
order by c2y.admissiond desc ) AS Date3,
(select top 1
CONVERT(VARCHAR(20),c5k.arrivaldat,103) ArrivalDate
from core_emergencyatten c5k
LEFT OUTER JOIN core_patient c6k ON c5k.patient = c6k.id
where (c6k.id = ca1.id)
order by c5k.arrivaldat desc ) AS Date4
from core_patient ca1
LEFT OUTER JOIN core_patient_c_identifi ca2 ON ca1.id = ca2.id
LEFT OUTER JOIN applookup_instance aa2 ON ca1.lkp_sex = aa2.id
LEFT OUTER JOIN applookup_instance aa1 ON ca2.lkp_c_ty = aa1.id
LEFT OUTER JOIN applookup_instance ab1 ON ca1.lkp_overseascl = ab1.id
LEFT OUTER JOIN core_organisation cx4 ON ca1.practice = cx4.id
WHERE ca1.id IN
(
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where ((ca2.merged = 0 or ca2.merged is null)
and aa1.id = -2404) )
AND ca1.id NOT IN (
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where (c1.namesurname not like '%XXTEST%'
and c1.namesurname not like '%ZZ%'
and a1.id = -9)
)
)Sub
You could do the following:
make your query into a CTE;
flatten the data so it becomes a list of PT_IDs and dates;
from this flattened data find the maximum and minimum date per PT_ID;
bring this all back together in one final query.
This is a stab at doing all of the above:
WITH x AS (
select distinct
ca1.id AS PT_ID,
(select Top 1 s1z.appointmen ApptDate
from schl_booking_appoin s1z
LEFT OUTER JOIN core_patient c3z ON s1z.patient = c3z.id
LEFT OUTER JOIN schl_appt_history_s s2z ON s1z.currentsta = s2z.id
LEFT OUTER JOIN applookup_instance a2z ON s2z.lkp_status = a2z.id
where (c3z.id = ca1.id and a2z.text not like '%cancelled%' and s1z.appointmen
> :SYS_DATE_TIME)
order by s1z.appointmen asc ) AS Date1,
(select Top 1
s1q.appointmen ApptDate
from schl_booking_appoin s1q
LEFT OUTER JOIN core_patient c3q ON s1q.patient = c3q.id
LEFT OUTER JOIN schl_appt_history_s s2q ON s1q.currentsta = s2q.id
LEFT OUTER JOIN applookup_instance a2q ON s2q.lkp_status = a2q.id
where (c3q.id = ca1.id and a2q.text not like '%cancelled%' and s1q.appointmen
< :SYS_DATE_TIME)
order by s1q.appointmen desc ) AS Date2,
(select top 1
CONVERT (VARCHAR(20),c2y.admissiond, 103) AdmissionDate
from core_admissiondetai c2y
LEFT OUTER JOIN core_pas_event c3y ON c2y.pasevent = c3y.id
LEFT OUTER JOIN core_patient c4y ON c3y.patient = c4y.id
where (c4y.id = ca1.id)
order by c2y.admissiond desc ) AS Date3,
(select top 1
CONVERT(VARCHAR(20),c5k.arrivaldat,103) ArrivalDate
from core_emergencyatten c5k
LEFT OUTER JOIN core_patient c6k ON c5k.patient = c6k.id
where (c6k.id = ca1.id)
order by c5k.arrivaldat desc ) AS Date4
from core_patient ca1
LEFT OUTER JOIN core_patient_c_identifi ca2 ON ca1.id = ca2.id
LEFT OUTER JOIN applookup_instance aa2 ON ca1.lkp_sex = aa2.id
LEFT OUTER JOIN applookup_instance aa1 ON ca2.lkp_c_ty = aa1.id
LEFT OUTER JOIN applookup_instance ab1 ON ca1.lkp_overseascl = ab1.id
LEFT OUTER JOIN core_organisation cx4 ON ca1.practice = cx4.id
WHERE ca1.id IN
(
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where ((ca2.merged = 0 or ca2.merged is null)
and aa1.id = -2404) )
AND ca1.id NOT IN (
select c1.id core_patient_c1_id
from core_patient c1
LEFT OUTER JOIN core_patient_c_identifi c2 ON c1.id = c2.id
LEFT OUTER JOIN applookup_instance a1 ON c2.lkp_c_ty = a1.id
where (c1.namesurname not like '%XXTEST%'
and c1.namesurname not like '%ZZ%'
and a1.id = -9)
)),
y AS (
SELECT PT_ID, Date1 AS [Date] FROM x WHERE Date1 IS NOT NULL
UNION ALL
SELECT PT_ID, Date2 AS [Date] FROM x WHERE Date2 IS NOT NULL
UNION ALL
SELECT PT_ID, Date3 AS [Date] FROM x WHERE Date3 IS NOT NULL
UNION ALL
SELECT PT_ID, Date4 AS [Date] FROM x WHERE Date4 IS NOT NULL),
z AS (
SELECT
PT_ID,
MIN([Date]) AS Min_Date,
MAX([Date]) AS Max_Date
FROM
y
GROUP BY
PT_ID)
SELECT
x.PT_ID,
x.Date1,
x.Date2,
x.Date3,
x.Date4,
z.Min_Date,
z.Max_Date
FROM
x
LEFT JOIN z ON z.PT_ID = x.PT_ID;

Need to replace case statement in where clause

**The below query is working badly, and I'm planning to replace case stmt in where clause with temp table. Pls suggest to me some option to rewrite this query
Is there a way to simplify this into multiple SQLs
Also explain me how this case stmt works in where clause**
select DISTINCT
ph.order_type_cd,
c.order_num,
ph.created_date,
os.order_status_desc,
ph.facility_name,
PH.vendor_order_num,
l.lic_nm,
(u.last_nm + ', ' + u.first_nm )as requestor_nm,
bl.billing_location_desc,
ph.ship_to_name,
dm.dispatch_method_name_desc as courier,
PH.po_last_updated_dt as last_updated_date,
(u1.last_nm + ', ' + u1.first_nm )as last_updated_by,
ph.right_grp_id,
c.line_id,
a.material_product_id,
a.parent_material_product_id
from avt_po_detail c
inner join avt_po_hdr ph on ph.order_num = c.order_num
left outer join avt_material_product AS a on a.material_product_id=c.material_product_id
INNER JOIN #entity_ids po on po.entity_id = c.order_num --or #select_pos = 0 )
LEFT OUTER JOIN dbo.ert_product AS pc ON pc.product_id = a.product_id
left outer join ert_product_type as pt on pt.product_type_cd = pc.product_type_cd
LEFT OUTER JOIN dbo.ert_product_xref as xref on xref.product_id = a.parent_product_id AND xref.version_id = 1
left outer join avt_order_status AS OS ON OS.order_status_cd = PH.order_status_cd
left outer join avt_licensee l on l.lic_id = ph.lic_id
left outer join avt_po_from pf on pf.material_product_id = a.material_product_id and pf.line_id = c.line_id
left outer join avt_po_audio_detail pad on pad.line_id = c.line_id
left outer join avt_materials_trans_material MTM on mtm.sequence_no = c.video_seq_no
left outer join avt_user u on u.userid = ph.requestor_id
left outer join avt_user u1 on u1.userid = ph.po_last_updated_by
left outer join avt_billing_location bl on bl.billing_location_cd = PH.billing_location_cd
left outer join avt_dispatch_method_name dm on dm.dispatch_method_name_id = PH.dispatch_method_name_id
left outer join avt_right_group arg on arg.right_grp_id = ph.right_grp_id
left outer join #prod product on product.product_id=a.product_id and (product.version_id=c.dist_version_id OR product.version_id = 1)
where (pf.from_desc in ( select from_desc from #from_desc ) or #select_form = 0)
and (case WHEN c.dist_version_id IS NULL THEN c.UCS_prod_no
ELSE
CASE
WHEN isnull(pt.version_control_ind, 'N') = 'Y' THEN xref.rss_prod_no
WHEN
isnull(pt.version_control_ind, 'N') = 'N' AND
xref.rss_prod_no IS NULL AND
xref.rss_film_id IS NULL THEN xref.rss_titleid
WHEN
isnull(pt.version_control_ind, 'N') = 'N' AND
xref.rss_prod_no IS NOT NULL AND
xref.rss_film_id IS NULL THEN substring(pc.glacct, 24, 5) -- ASR 3290687
WHEN isnull(pt.version_control_ind, 'N') = 'N' AND xref.rss_film_id IS NOT NULL THEN isnull(substring(pc.glacct, 24, 5), -- ASR 3290687
(
SELECT substring(dbo.ert_product.glacct, 24, 5) -- ASR 3290687
FROM dbo.ert_product
WHERE dbo.ert_product.product_id = a.parent_product_id
))
END
END in (select prod_no from #prod_no) or #prod_no = 0)

I receive conversion varchar to float error when insert **set rowcount=1** in first line of code

I receive an error
Coversion of varchar to float
when I write
set rowcount = 1
on first line of my code.
My script is:
select
vh.VchNum, ct.Val, r.RoutSheetNo, vi.FinalQty,
rh.RequestNo, vh.VchDate,
p.PartCode, d.Title, co.val
from
inv.InvVchHdr vh
join
acc.DL d on d.AccNum = vh.DLREF
join
inv.InvVchItm vi on vi.VchHdrRef = vh.VchHdrID
join
inv.InvVchItmCtrl ct on ct.VchItmRef = vi.VchItmID
join
QCS.QcsCertificateOfAnalysis q on q.Number = ct.Val
join
USR.kalaf_info_p kp on kp.Id = q.QcsCertificateOfAnalysisId
join
USR.coil_trace co on co.id = kp.coil_id
join
inv.Part p on p.Serial = vi.PartRef
join
inv.InvRqstItm rq on rq.RqstItmID = vi.RefNum
join
inv.InvRqstHdr rh on rh.RqstHdrID = rq.HdrRef
join
PRD.vwPrdOrderItemPlan pl on rh.OrdPlnBase = pl.OrdPlnId
join
prd.prdroutsheet r on r.OrdPlnRef = pl.OrdPlnId
where
pl.pPartRef not in (select pipe_code from usr.pipe_kalaf)
and pl.pPartRef not in (select Serial from inv.Part where PartName like '%لاف%')
and vi.VchType = 57
union
select vh.VchNum,ct.Val,pl.OrdPlnNo
,vi.FinalQty,
rh.RequestNo,vh.VchDate,
p.PartCode,d.Title,co.val from
inv.InvVchHdr vh
join acc.DL d
on d.AccNum=vh.DLREF
join
inv.InvVchItm vi
on vi.VchHdrRef=vh.VchHdrID
join inv.InvVchItmCtrl ct
on ct.VchItmRef=vi.VchItmID
join QCS.QcsCertificateOfAnalysis q
on q.Number=ct.Val
join USR.kalaf_info_p kp
on kp.Id=q.QcsCertificateOfAnalysisId
join USR.coil_trace co
on co.id=kp.coil_id
join
inv.Part p
on p.Serial=vi.PartRef
join inv.InvRqstItm rq
on rq.RqstItmID=vi.RefNum
join inv.InvRqstHdr rh
on rh.RqstHdrID=rq.HdrRef
join PRD.vwPrdOrderItemPlan pl
on rh.OrdPlnBase=pl.OrdPlnId
where pl.pPartRef in (select pipe_code from usr.pipe_kalaf) and vi.VchType=57
SET ROWCOUNT 0
i use sql server 2000 and when I remove setrowcount statement, problem resolve.
please help me
Remove the =(equal) sign
from
set rowcount = 1
To
SET ROWCOUNT 1