Sql query for following scenario - sql

I have following scenario, for which i need to write sql query.
I have ICCID table and ICCID property table which holds following information.
I want to find out all active iccids and iccid's which are in removed state in month of december 2012.for ICCIDs which are in removed state, date.to.change key in the ICCID property table itself which record the removed date of ICCID.
this is my attempt, but that did not worked
select e.ID_ICCID from ICCID_PROPERTY e where
e.c_key ='STATE' and e.c_value='Active' or(
e.c_key ='STATE' and
e.c_value='Removed' and
e.c_key='date.to.change' and
to_date(e.c_value,'yyyymmdd') >=to_date('2012-DEC-01 00:00:00', 'YYYY-MON-DD HH24:MI:SS') and
to_date(e.c_value,'yyyymmdd') <= to_date('2012-DEC-31 23:59:59', 'YYYY-MON-DD HH24:MI:SS')
))
Thanks in advance for any help

This is one of the issues with a key-value pair design such as this...
You can't just check a single property row to see if it matches the search criteria, since the criteria in this case will span multiple properties... you have to check if a single parent row has all the children properties that match:
SELECT
i.ICCID
FROM
ICCID i
WHERE
EXISTS (
SELECT 1
FROM ICCID_PROPERTY ip
WHERE
ip.ID_ICCID = i.ID_ICCID
AND ip.c_key = 'STATE'
AND ip.c_value = 'Active'
) OR (
EXISTS (
SELECT 1
FROM ICCID_PROPERTY ip
WHERE
ip.ID_ICCID = i.ID_ICCID
AND ip.c_key = 'STATE'
AND ip.c_value = 'Removed'
) AND
EXISTS (
SELECT 1
FROM ICCID_PROPERTY ip
WHERE
ip.ID_ICCID = i.ID_ICCID
AND ip.c_key = 'date.to.change'
AND to_date(ip.c_value,'yyyymmdd') >=
to_date('2012-DEC-01 00:00:00', 'YYYY-MON-DD HH24:MI:SS')
AND to_date(ip.c_value,'yyyymmdd') <=
to_date('2012-DEC-31 23:59:59', 'YYYY-MON-DD HH24:MI:SS')
)
)

I think you could join the Property table three times -- maybe something like this (untested):
SELECT I.ID_ICCID
FROM ICCID I
JOIN ICCID_Property IP ON I.ID_ICCID = IP.ID_ICCID AND IP.C_Key = 'STATE' AND IP.C_Value = 'Active'
JOIN ICCID_Property IP2 ON I.ID_ICCID = IP.ID_ICCID AND IP2.C_Key = 'STATE' AND IP2.C_Value= 'Removed'
JOIN ICCID_Property IP3 ON I.ID_ICCID = IP.ID_ICCID AND IP3.C_Key = 'date.to.change' AND to_date(IP3.C_Value,'yyyymmdd') >= to_date('2012-DEC-01 00:00:00', 'YYYY-MON-DD HH24:MI:SS')
AND to_date(IP3.C_Value,'yyyymmdd') <=
to_date('2012-DEC-31 23:59:59', 'YYYY-MON-DD HH24:MI:SS')
Good luck.

Related

Inserting parameters to SQL query in Oracle SQL

In the following query between date time columns are repeated in multiple places and I need to replace them with two variables named start_date and end_date I tried multiple methods and had no luck. Please answer with a runnable query if you can. Thanks in advance.
WITH encounter
AS (SELECT patient_pomr_id AS encounter_number,
patient_id AS umrn,
doctor_id,
doctor_name
FROM eh_pomr.ehpom_patient_pomr
WHERE created_on BETWEEN timestamp '2022-08-01 00:00:00' AND
timestamp '2022-08-30 00:00:00'),
chief_complain
AS (SELECT chief_complain,
patient_pomr_id
FROM eh_pomr.ehpom_chief_complain),
admission
AS (SELECT admitted_date,
patient_id,
ADMISSION_ID,
admission_type AS encounter_type,
patient_pomr_id,
hospital_id,
clinic_name
FROM ad_request.admlm_admission
WHERE direct_admission IS NULL
AND is_from_er != 1
AND created_date BETWEEN timestamp '2022-08-01 00:00:00' AND
timestamp '2022-08-30 00:00:00'),
ip_create_admission
AS (SELECT patientpomr,
dbms_lob.Substr(admitting_diagnosis, 2000, 1) diagnosis
FROM eh_ip.ehip_create_admission
WHERE created_on BETWEEN timestamp '2022-08-01 00:00:00' AND
timestamp '2022-08-30 00:00:00'),
discharge
AS (SELECT CASE
WHEN dischargevia = 1 THEN 'Private Vehicle'
WHEN dischargevia = 2 THEN 'Ambulatory'
WHEN dischargevia = 3 THEN 'Other'
ELSE ' Unknown'
END AS dischargevia,
pomrid,
modifiedon AS discharge_date,
conditionondischarge AS discharge_speciality
FROM eh_ndischarge.ehipd_dischargedetails
WHERE isactive = 1),
death
AS (SELECT dbms_lob.Substr(underlying_cause, 2000, 1) cause_of_death,
patientpomr
FROM eh_ip.ehip_death_detail),
empi
AS (SELECT id_number,
mrn
FROM rf_empi.emred_patients),
vitals
AS (SELECT PR.id,
PR.patient_pomr_id,
FS.field_code,
FS.value
FROM eh_commmon.ehcom_patient_record PR
left join eh_commmon.ehcom_flow_sheet_data FS
ON PR.id = FS.patient_record_id
WHERE PR.flow_sheet_code = 'vitals'
AND FS.time_stamp BETWEEN timestamp '2022-08-01 00:00:00' AND
timestamp '2022-08-30 00:00:00'),
leaves
AS (SELECT requesting_days,
visit_id,
ADM.PATIENT_POMR_ID
FROM ad_request.admlm_med_leave_final_print FP
left join ad_request.admlm_medical_leave ML
ON FP.request_id = ML.request_id
LEFT JOIN AD_REQUEST.ADMLM_ADMISSION ADM
ON ML.VISIT_ID = ADM.ADMISSION_ID
WHERE FP.leave_status = 5
AND ML.created_date BETWEEN timestamp '2022-08-01 00:00:00' AND
timestamp '2022-08-30 00:00:00'
AND ML.REQUESTING_DAYS IS NOT NULL)
SELECT DISTINCT encounter.encounter_number,
admission.encounter_type,
empi.id_number AS Patient_National_ID,
admission.patient_id AS umrn,
admission.admitted_date,
admission.hospital_id,
admission.clinic_name AS admission_speciality,
chief_complain.chief_complain,
leaves.requesting_days AS Duration_of_leave,
encounter.doctor_id,
encounter.doctor_name,
ip_create_admission.diagnosis,
discharge.dischargevia,
discharge.discharge_date,
discharge_speciality,
admission.clinic_name AS clinic,
death.cause_of_death
-- VITALS.field_code,
-- VITALS.value
FROM admission
left join empi
ON admission.patient_id = empi.mrn
left join encounter
ON admission.patient_pomr_id = encounter.encounter_number
left join ip_create_admission
ON admission.patient_pomr_id = ip_create_admission.patientpomr
--admission_request_numbrer with adt
left join discharge
ON admission.patient_pomr_id = discharge.pomrid
left join death
ON admission.patient_pomr_id = death.patientpomr
left join chief_complain
ON admission.patient_pomr_id = chief_complain.patient_pomr_id
left join leaves
ON admission.patient_pomr_id = leaves.PATIENT_POMR_ID
I tried adding with begin and end tags with declare key words but had no luck. Also is there a special way to insert variable using in to keyword when we need to insert it for between?
Include yet another CTE (I'm calling it dates) which is then cross-joined in another CTEs which utilize these values. Something like this:
WITH
dates (start_date, end_date) --> this is new CTE
AS (SELECT timestamp '2022-08-01 00:00:00',
timestamp '2022-08-30 00:00:00'
FROM dual),
encounter
AS (SELECT patient_pomr_id AS encounter_number,
patient_id AS umrn,
doctor_id,
doctor_name
FROM eh_pomr.ehpom_patient_pomr
CROSS JOIN dates d --> it is used here
WHERE created_on BETWEEN d.start_date AND d.end_date), --> like this
chief_complain
AS ..
This is from MSSQL, you can try converting this through OracleSQL
#dateFrom datetime = null,
#dateTo datetime = null,
DATEADD(D, 0, DATEDIFF(D, 0, #DateFrom))
AND DATEADD(D, 0, DATEDIFF(D, 0, #DateTo))

Combine 2 sql queries into one with eliminating duplicate colums

I have written 2 sql queries by using multiple join statements.
Now I want to combine both the query results as below.
First query shows these columns
UDC_ID, EXT_ID, VALUE
The second query shows these columns
UDC_ID, EXT_ID, VALUE
In both the queries UDC_ID and EXT_ID columns are the same, but the VALUE column in each is different
So the final output I want to display is,
UDC_ID, EXT_ID, VALUE (From Query1), VALUE (from Query 2)
Can anyone suggest how this can be achieved?
These are my queries:
Query 1 joins three tables:
SELECT
DEV.UDC_ID,
SR.EXT_ID,
SRA.VALUE
FROM SERVICE_REQUEST SR
JOIN DEVICE DEV
ON SR.DEVICE_ID = DEV.ID
JOIN SERVICE_REQUEST_ATTR SRA
ON SR.ID = SERVICE_REQUEST_ID
WHERE SR.SUB_TYPE_CD = 'HMI_22'
--AND DEV.SUB_TYPE = 'ESME'
AND SRA.NAME = 'CommsHubGUID'
AND SR.INSERT_TIME >= TO_DATE('2016-09-21 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
AND SR.INSERT_TIME <= TO_DATE('2016-09-28 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
ORDER BY SR.INSERT_TIME DESC;
The difference between query 1 and this query is the where clause criterion for SRA.NAME field, otherwise both the queries are same.
SELECT
DEV.UDC_ID,
SR.EXT_ID,
SRA.VALUE
FROM SERVICE_REQUEST SR
JOIN DEVICE DEV
ON SR.DEVICE_ID = DEV.ID`enter code here`
JOIN SERVICE_REQUEST_ATTR SRA
ON SR.ID = SERVICE_REQUEST_ID
WHERE SR.SUB_TYPE_CD = 'HMI_22'
--AND DEV.SUB_TYPE = 'ESME'
AND SRA.NAME = 'Service Location'
AND SR.INSERT_TIME >= TO_DATE('2016-09-21 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
AND SR.INSERT_TIME <= TO_DATE('2016-09-28 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
ORDER BY SR.INSERT_TIME DESC
SELECT COALESCE(q1.UDC_ID,q2.UDC_ID),
COALESCE(q1.EXT_ID, q2.EXT_ID),
q1.VALUE ,
q2.VALUE
FROM (query 1) q1
FULL OUTER JOIN (query 2) q2 ON q1.UDC_ID=q2.UDC_ID and q1.EXT_ID=q2.EXT_ID

how to join 2 query into one in EXCEL ORACLE CONNECTION

I have 2 query.
I am trying to join them so I just write export from one instead of manually joining them in excel.
(SELECT
b.OUT_NO,
a.ACCNO,
a.BILL_ACCNO,
a.NAME,
a.HOUSE_NO,
a.STREET,
a.HOUSE_NO2,
a.ZIP,
a.ID,
b.TIME_STAMP,
b.REST_DATE,
c.RESTORED_TIME,
b.OUT_CMNT
FROM brook.account a,
brook.problem b,
brook.history c
WHERE c.OUT_NO = b.OUT_NO
AND a.ID = c.ID
AND ( (a.NAME Is Not Null)
AND (a.DISC Is Null)
AND (b.TIME_STAMP>?)
AND (c.RESTORED_TIME<?))
)
and
(SELECT
b.OUT_NO,
a.ACCNO,
a.BILL_ACCNO,
a.NAME,
a.HOUSE_NO,
a.STREET,
a.HOUSE_NO2,
a.ZIP,
a.ID,
b.TIME_STAMP,
b.REST_DATE,
c.RESTORED_TIME,
b.OUT_CMNT
FROM brook.account a,
brook.problem b,
brook.history c
WHERE c.OUTAGE_NO = b.OUTAGE_NO
AND a.ID = c.ID
AND ( (a.NAME Is Not Null)
AND (a.DISC Is Null)
AND (b.TIME_STAMP > ? And b.TIME_STAMP < ?)
AND (c.RESTORED_TIME > ? And c.RESTORED_TIME < ?)
)
)
How can I join these 2? into 1, I tried UNION ALL but I get ora-01847 day of month must be between 1 and last day of month ERROR.
? are the parameter, it is linked to cells on spreadsheet.
format of excel data parameter. 11/04/2013 00:00:00
Thanks
Error is about a date format, not about union.
If you pass cell values as string parameters Oracle tries to convert it to dates to comapre with columns of date or timestamp values in table columns. To do this conversion Oracle uses it's internal default date representation format wich is not mm/dd/yyyy hh24:mi:ss in your case.
There are 2 possibilities to fix a situation:
Pass parameters with date type to query and convert values to dates before passing it to Oracle. Check examples on MSDN and description of CreateParameter and Parameters.Append methods.
Convert values to dates in query with to_date Oracle function.
Change conditions in query from
AND (b.TIME_STAMP>?)
AND (c.RESTORED_TIME<?))
and
AND (b.TIME_STAMP > ? And b.TIME_STAMP < ?)
AND (c.RESTORED_TIME > ? And c.RESTORED_TIME < ?)
to
AND (b.TIME_STAMP > to_date(?,'mm/dd/yyyy hh24:mi:ss') )
AND (c.RESTORED_TIME < to_date(?,'mm/dd/yyyy hh24:mi:ss') ))
and
AND (
b.TIME_STAMP > to_date(?,'mm/dd/yyyy hh24:mi:ss')
And
b.TIME_STAMP < to_date(?,'mm/dd/yyyy hh24:mi:ss')
)
AND (
c.RESTORED_TIME > to_date(?,'mm/dd/yyyy hh24:mi:ss')
And
c.RESTORED_TIME < to_date(?,'mm/dd/yyyy hh24:mi:ss')
)

Convert a nested subquery into normal query

I have problem with following query where in which the nested query should be
converted to normal query:
select
count(*) as count,
TO_CHAR(RH.updated_datetime,'DD-MM-YYYY HH:MI:SS') as date,
SUM(
extract (
epoch from (
RH.updated_datetime - PRI.procedure_performed_datetime
)
)/60
)::integer/count(*) as diff
from
procedure_runtime_information PRI,
study S,
report R,
report_history RH
where
RH.report_fk = R.pk AND
R.study_fk = S.pk AND
S.procedure_runtime_fk = PRI.pk AND
RH.old_status_fk = 21 AND
RH.revision = (select max(revision) from report_history where RH.report_fk = RH.report_fk) AND
RH.updated_datetime > TO_DATE('22-01-2013 00:00:00', 'DD-MM-YYYY HH24:MI:SS') AND RH.updated_datetime < TO_DATE('22-01-2014 00:00:00', 'DD-MM-YYYY HH24:MI:SS')
group by date order by date asc;
Assuming this
(select max(revision) from report_history where RH.report_fk = RH.report_fk)
should really be:
(select max(revision) from report_history x where x.report_fk = RH.report_fk)
You could transform the nested (correlated) subquery into a plain subquery like this (one way of many):
SELECT count(*) AS ct
,to_char(rh.updated_datetime,'DD-MM-YYYY HH:MI:SS') AS date -- HH24?
,sum(extract(epoch FROM (RH.updated_datetime
- PRI.procedure_performed_datetime))
/ 60)::int / count(*) AS diff
FROM procedure_runtime_information PRI
JOIN study S ON S.procedure_runtime_fk = PRI.pk
JOIN report R ON R.study_fk = S.pk
JOIN report_history RH ON RH.report_fk = R.pk
JOIN (
SELECT report_fk, max(revision) AS revision
FROM report_history RH1
GROUP BY 1
) RH1 ON RH1.report_fk = RH.report_fk
AND RH1.revision = RH.revision
WHERE RH.old_status_fk = 21
AND RH.updated_datetime > to_date('22-01-2013', 'DD-MM-YYYY') -- >= ?
AND RH.updated_datetime < to_date('22-01-2014', 'DD-MM-YYYY') -- to_timestamp?
GROUP BY date -- where does date come from?
ORDER BY date;

Oracle SQL Correlated Subquery (in WHERE statement) having no results

Hi and thanks for reading,
I am trying to run the following SQL query with correlated subquery and it is bringing back no results. I am using the subquery to only bring back results that have the lowest date range. Both the query alone and the subquery alone work fine.
Any ideas? Am I linking the correlated subquery incorrectly?
Note: The correlated subquery is on the last line of the query
Thank you,
Willz06jw
SELECT aaa."effective_time",
aaa."event_type_c",
"clarity_dep"."department_name",
"patient"."birth_date",
"patient"."pat_mrn_id",
"zc_ped_delivr_meth"."name",
"zc_ped_delivr_meth"."ped_delivr_meth_c",
aaa."department_id",
"clarity_dep"."department_id",
aaa."alt_event_type_c",
aaa."in_event_type_c"
FROM (("CLARITY"."clarity_adt" aaa
inner join "CLARITY"."clarity_dep" "CLARITY_DEP"
ON aaa."department_id" = "clarity_dep"."department_id")
inner join "CLARITY"."patient" "PATIENT"
ON aaa."pat_id" = "patient"."pat_id")
inner join "CLARITY"."zc_ped_delivr_meth" "ZC_PED_DELIVR_METH"
ON "patient"."ped_delivr_meth_c" =
"zc_ped_delivr_meth"."ped_delivr_meth_c"
WHERE ( "patient"."birth_date" >= To_date ('01-12-2012 00:00:00',
'DD-MM-YYYY HH24:MI:SS')
AND "patient"."birth_date" < To_date ('06-12-2012 00:00:00',
'DD-MM-YYYY HH24:MI:SS'
) )
AND ( aaa."department_id" = 236601
OR aaa."department_id" = 236703
OR aaa."department_id" = 236801
OR aaa."department_id" = 236901
OR aaa."department_id" = 237101
OR aaa."department_id" = 237201 )
AND aaa."event_type_c" = 3
AND aaa."effective_time" = (SELECT Min(bbb."effective_time")
FROM "clarity_adt" bbb
WHERE aaa."pat_id" = bbb.pat_id)
Without zifting through the entire statement, the easiest solution would be to just wrap the statement in a select using the ROW_NUMBER function to get the lowest dates.
SQL Statement 1
SELECT *
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY pat_id ORDER BY effective_time) AS rn,
aaa."effective_time",
aaa."event_type_c",
"clarity_dep"."department_name",
"patient"."birth_date",
"patient"."pat_mrn_id",
"zc_ped_delivr_meth"."name",
"zc_ped_delivr_meth"."ped_delivr_meth_c",
aaa."department_id",
"clarity_dep"."department_id",
aaa."alt_event_type_c",
aaa."in_event_type_c"
FROM "CLARITY"."clarity_adt" aaa
inner join "CLARITY"."clarity_dep" "CLARITY_DEP" ON aaa."department_id" = "clarity_dep"."department_id"
inner join "CLARITY"."patient" "PATIENT" ON aaa."pat_id" = "patient"."pat_id"
inner join "CLARITY"."zc_ped_delivr_meth" "ZC_PED_DELIVR_METH" ON "patient"."ped_delivr_meth_c" = "zc_ped_delivr_meth"."ped_delivr_meth_c"
WHERE ( "patient"."birth_date" >= To_date ('01-12-2012 00:00:00', 'DD-MM-YYYY HH24:MI:SS')
AND "patient"."birth_date" < To_date ('06-12-2012 00:00:00', 'DD-MM-YYYY HH24:MI:SS' ) )
AND ( aaa."department_id" = 236601 OR aaa."department_id" = 236703 OR aaa."department_id" = 236801 OR aaa."department_id" = 236901 OR aaa."department_id" = 237101 OR aaa."department_id" = 237201 )
AND aaa."event_type_c" = 3
) q
WHERE q.rn = 1
Your statement could be simplified (in reading it) by using an IN statement io. all the ORstatements like such
SQL Statement 2
SELECT *
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY pat_id ORDER BY effective_time) AS rn,
aaa."effective_time",
aaa."event_type_c",
"clarity_dep"."department_name",
"patient"."birth_date",
"patient"."pat_mrn_id",
"zc_ped_delivr_meth"."name",
"zc_ped_delivr_meth"."ped_delivr_meth_c",
aaa."department_id",
"clarity_dep"."department_id",
aaa."alt_event_type_c",
aaa."in_event_type_c"
FROM "CLARITY"."clarity_adt" aaa
inner join "CLARITY"."clarity_dep" "CLARITY_DEP" ON aaa."department_id" = "clarity_dep"."department_id"
inner join "CLARITY"."patient" "PATIENT" ON aaa."pat_id" = "patient"."pat_id"
inner join "CLARITY"."zc_ped_delivr_meth" "ZC_PED_DELIVR_METH" ON "patient"."ped_delivr_meth_c" = "zc_ped_delivr_meth"."ped_delivr_meth_c"
WHERE ( "patient"."birth_date" >= To_date ('01-12-2012 00:00:00', 'DD-MM-YYYY HH24:MI:SS')
AND "patient"."birth_date" < To_date ('06-12-2012 00:00:00', 'DD-MM-YYYY HH24:MI:SS' ) )
AND ( aaa."department_id" IN (236601,236703,236801,236901,237101,237201) )
AND aaa."event_type_c" = 3
) q
WHERE q.rn = 1
In the end, I would even simplify it further by aliassing all tables and use a WITH statement. The final result would look like this
SQL Statement 3
;WITH q AS (
SELECT ROW_NUMBER() OVER (PARTITION BY pat_id ORDER BY effective_time) AS rn,
aaa."effective_time",
aaa."event_type_c",
cd."department_name",
p."birth_date",
p."pat_mrn_id",
pdm."name",
pdm."ped_delivr_meth_c",
aaa."department_id",
cd."department_id",
aaa."alt_event_type_c",
aaa."in_event_type_c"
FROM "CLARITY"."clarity_adt" aaa
inner join "CLARITY"."clarity_dep" cd ON aaa."department_id" = cd."department_id"
inner join "CLARITY"."patient" p ON aaa."pat_id" = p."pat_id"
inner join "CLARITY"."zc_ped_delivr_meth" pdm ON p."ped_delivr_meth_c" = pdm."ped_delivr_meth_c"
WHERE p."birth_date" >= To_date ('01-12-2012 00:00:00', 'DD-MM-YYYY HH24:MI:SS'
AND p."birth_date" < To_date ('06-12-2012 00:00:00', 'DD-MM-YYYY HH24:MI:SS' ) )
AND aaa."department_id" IN (236601,236703,236801,236901,237101,237201)
AND aaa."event_type_c" = 3
)
SELECT *
FROM q
WHERE rn = 1
You're only going to get rows if the row with the earliest date also matches the other conditions on clarity_adt. If you want the earliest record for that subset then you'd have to push those conditions into the subquery.