How to combine two queries to get one result? - sql

I need two combine two queries to get one result only. Here's the first code.
SELECT FKLTI_KTRGN, COUNT(DISTINCT VIEW_PELAJAR_ENROLL.MB_NAMA) AS BIL_UG
FROM VIEW_PELAJAR_ENROLL, KOD_BANGSA, KOD_NEGERI, JANTINA, KOD_AGAMA, KOD_CACAT, TARAF_KAHWIN
WHERE KOD_KTRGN_PROGRAM = 'SARJANA MUDA'
AND MS_SESI = '2015/2016'
AND MB_BANGSA = KOD_BANGSA
AND KOD_NEGERI = MB_ASAL
AND MB_JANTINA = JAN_KOD
AND KOD_AGAMA = MB_AGAMA
AND KOD_CACAT = MB_CACAT
AND KOD_TARAF = MB_TARAF_KAHWIN
AND MS_STATUS_SEMASA IN
(SELECT SP_KOD
FROM STATUS_PELAJAR
WHERE STATUS_ENROLL = 'Y'
AND SP_TAMAT IS NULL
AND SP_KOD = MS_STATUS_SEMASA)
GROUP BY FKLTI_KTRGN
And this is the second code.
SELECT FKLTI_KTRGN, COUNT(DISTINCT PELAJAR_BIODATA.MBUT_NAMA) AS BIL_PG
FROM PELAJAR_BIODATA,KOD_NEGERI,FAKULTI,KOD_IJAZAH,PELAJAR_BUTIR_PENGAJIAN,STATUS_PENGAJIAN A,
KOD_STATUS_PELAJAR_IPS, KOD_CACAT, KOD_BANGSA, E_KOD_PENGAJIAN, JANTINA, KOD_PROGRAM
WHERE A.STAT_STATUS IN (SELECT KOD_STATUS
FROM KOD_STATUS_PELAJAR_IPS
WHERE STATUS_ENROLL='Y'
AND KOD_STATUS=STAT_STATUS)
AND A.STAT_NOMKPB=MBUT_NOMKPB
AND PBP_PROGRAM IN ('5','6')
AND MBUT_ASAL=KOD_NEGERI(+)
AND SUBSTR(A.STAT_KOD_IJAZAH,1,1)=FKLTI_KOD
AND PBP_PROGRAM=KOD_PROGRAM.KOD_PROGRAM
AND A.STAT_KOD_IJAZAH=KOD_IJAZAH_UM
AND A.STAT_NODAFTAR=PBP_NODAFTAR
AND MBUT_CACAT=KOD_CACAT
AND KOD_BANGSA=MBUT_BANGSA
AND PBP_JENIS_PENGAJIAN=KOD_JNS_PENGAJIAN
AND MBUT_JANTINA=JAN_KOD
AND MBUT_WARGA IS NOT NULL
AND MBUT_BANGSA IS NOT NULL
AND MBUT_JANTINA IS NOT NULL
AND MBUT_NEGERI IS NOT NULL
AND PBP_PROGRAM IS NOT NULL
AND A.STAT_STATUS=KOD_STATUS
AND PBP_KOD_IJAZAH IS NOT NULL
AND A.STAT_SESI||A.STAT_SEMESTER IN (SELECT MAX(B.STAT_SESI||B.STAT_SEMESTER) FROM STATUS_PENGAJIAN B
WHERE B.STAT_NODAFTAR=A.STAT_NODAFTAR
AND B.STAT_NOMKPB=A.STAT_NOMKPB
AND A.STAT_SESI||A.STAT_SEMESTER=B.STAT_SESI||B.STAT_SEMESTER)
AND A.STAT_SESI = '2015/2016'
group by FKLTI_KTRGN
This is the expected result:
This is what i get:
I've tried to use UNION but it doesn't work. Anyone can help me? I really need your help. Thank you in advance!

In order to use union, you need to have the same number of fields and the same field name of both query.
as in both queries of yours, the second field has different name: BIL_PG, BIL_UG

Try this
select * from
(SELECT FKLTI_KTRGN, COUNT(DISTINCT VIEW_PELAJAR_ENROLL.MB_NAMA) AS BIL_UG
FROM VIEW_PELAJAR_ENROLL, KOD_BANGSA, KOD_NEGERI, JANTINA, KOD_AGAMA, KOD_CACAT, TARAF_KAHWIN
WHERE KOD_KTRGN_PROGRAM = 'SARJANA MUDA'
AND MS_SESI = '2015/2016'
AND MB_BANGSA = KOD_BANGSA
AND KOD_NEGERI = MB_ASAL
AND MB_JANTINA = JAN_KOD
AND KOD_AGAMA = MB_AGAMA
AND KOD_CACAT = MB_CACAT
AND KOD_TARAF = MB_TARAF_KAHWIN
AND MS_STATUS_SEMASA IN
(SELECT SP_KOD
FROM STATUS_PELAJAR
WHERE STATUS_ENROLL = 'Y'
AND SP_TAMAT IS NULL
AND SP_KOD = MS_STATUS_SEMASA)
GROUP BY FKLTI_KTRGN)
union
select * from (SELECT FKLTI_KTRGN, COUNT(DISTINCT PELAJAR_BIODATA.MBUT_NAMA) AS BIL_PG
FROM PELAJAR_BIODATA,KOD_NEGERI,FAKULTI,KOD_IJAZAH,PELAJAR_BUTIR_PENGAJIAN,STATUS_PENGAJIAN A,
KOD_STATUS_PELAJAR_IPS, KOD_CACAT, KOD_BANGSA, E_KOD_PENGAJIAN, JANTINA, KOD_PROGRAM
WHERE A.STAT_STATUS IN (SELECT KOD_STATUS
FROM KOD_STATUS_PELAJAR_IPS
WHERE STATUS_ENROLL='Y'
AND KOD_STATUS=STAT_STATUS)
AND A.STAT_NOMKPB=MBUT_NOMKPB
AND PBP_PROGRAM IN ('5','6')
AND MBUT_ASAL=KOD_NEGERI(+)
AND SUBSTR(A.STAT_KOD_IJAZAH,1,1)=FKLTI_KOD
AND PBP_PROGRAM=KOD_PROGRAM.KOD_PROGRAM
AND A.STAT_KOD_IJAZAH=KOD_IJAZAH_UM
AND A.STAT_NODAFTAR=PBP_NODAFTAR
AND MBUT_CACAT=KOD_CACAT
AND KOD_BANGSA=MBUT_BANGSA
AND PBP_JENIS_PENGAJIAN=KOD_JNS_PENGAJIAN
AND MBUT_JANTINA=JAN_KOD
AND MBUT_WARGA IS NOT NULL
AND MBUT_BANGSA IS NOT NULL
AND MBUT_JANTINA IS NOT NULL
AND MBUT_NEGERI IS NOT NULL
AND PBP_PROGRAM IS NOT NULL
AND A.STAT_STATUS=KOD_STATUS
AND PBP_KOD_IJAZAH IS NOT NULL
AND A.STAT_SESI||A.STAT_SEMESTER IN (SELECT MAX(B.STAT_SESI||B.STAT_SEMESTER) FROM STATUS_PENGAJIAN B
WHERE B.STAT_NODAFTAR=A.STAT_NODAFTAR
AND B.STAT_NOMKPB=A.STAT_NOMKPB
AND A.STAT_SESI||A.STAT_SEMESTER=B.STAT_SESI||B.STAT_SEMESTER)
AND A.STAT_SESI = '2015/2016'
group by FKLTI_KTRGN)

Related

Select the first row that meets a condition + 1 row above

I have written a SQL query to return the following results:
Rows returned
However, I need to further 'filter' it down to only the rows highlighted in yellow, because I want the first row that has param_id = 'update_flag' AND param_val = '1'. I also need the row above that, because I need to retrieve the param_val value (202017) that corresponds to param_id = 'period_from' for the same Order Number (156 in this example).
This is my code, I'm getting data from 2 different tables:
SELECT
report1.orderno AS t1_orderno,
report2.orderno AS t2_orderno,
report1.report_name AS t1_reportname,
report2.report_name AS t2_reportname,
report1.variant,
report1.status,
report1.client,
report2.param_id,
report2.param_val
FROM report1
INNER JOIN
report2
ON report1.orderno = report2.orderno
AND report2.param_id IN
(
'period_from',
'update_flag'
)
AND report1.report_name = 'PR28'
AND report1.variant = '20'
AND report1.status = 'T'
AND report1.client = '10'
ORDER BY
report1.orderno DESC
Thanks for any help in advance, it's doing my head in!
WITH num_row AS (
SELECT row_number() OVER (ORDER BY report1.orderno DESC) as nom,
report1.orderno AS t1_orderno,
report2.orderno AS t2_orderno,
report1.report_name AS t1_reportname,
report2.report_name AS t2_reportname,
report1.variant,
report1.status,
report1.client,
report2.param_id,
report2.param_val
FROM report1
INNER JOIN
report2
ON report1.orderno = report2.orderno
AND report2.param_id IN (
'period_from',
'update_flag'
)
AND report1.report_name = 'PR28'
AND report1.variant = '20'
AND report1.status = 'T'
AND report1.client = '10'
)
SELECT * FROM num_row
WHERE nom BETWEEN 1 AND 2

select subquery using data from the select statement?

I have two tables, headers and lines. I need to grab the batch_submission_date from the header table, but sometimes a query for batch_id will return a null for batch_submission_date, but will also return a parent_batch_id, and if we query THAT parent_batch_id as a batch_id, it will then return the correct batch_submission_date.
e.g.
SELECT t1.batch_id,
t1.parent_batch_id,
t2.batch_submission_date
FROM db.headers t1, db.lines t2
WHERE t1.batch_id = '12345';
output = 12345, 99999, null
Then we use that parent batch_id as a batch_id :
SELECT t1.batch_id,
t1.parent_batch_id,
t2.batch_submission_date
FROM db.headers t1, db.lines t2
WHERE t1.batch_id = '99999';
and we get output = 99999,99999,'2018-01-01'
So I'm trying to write a query that will do this for me - anytime a batch_id's batch_submission_date is null, we find that batch_id's parent batch_id and query that instead.
This was my idea - but I just get back null both for bp_batch_submission_date and for new_submission_date.
SELECT
t1.parent_id as parent_id,
t1.BATCH_ID as bp_batch_id,
t2.BATCH_LINE_NUMBER as bp_batch_li,
t1.BATCH_SUBMISSION_DATE as bp_batch_submission_date,
CASE
WHEN t1.BATCH_SUBMISSION_DATE is null
THEN
(SELECT a.BATCH_SUBMISSION_DATE
FROM
db.headers a,
db.lines b
WHERE
a.SD_BATCH_HEADERS_SKEY = b.SD_BATCH_HEADERS_SKEY
and a.parent_batch_id = bp_batch_id
and b.batch_line_number = bp_batch_li
) END as new_submission_date
FROM
db.headers t1,
db.lines t2
WHERE
t1.SD_BATCH_HEADERS_SKEY = t2.SD_BATCH_HEADERS_SKEY
and (t1.BATCH_ID = '12345' or t1.PARENT_BATCH_ID = '12345')
and t2.BATCH_LINE_NUMBER = '1'
GROUP BY
t2.BATCH_CLAIM_LINE_STATUS_DESC,
t1.PARENT_BATCH_ID,
t1.BATCH_ID,
t2.BATCH_LINE_NUMBER,
t1.BATCH_SUBMISSION_DATE;
is what I'm trying to do possible? using the bp_batch_id and bp_batch_li variables
Use CTE (common table expression) to avoid redundant code, then use coalesce() to find parent date in case of null. In your first queries you didn't attach joining condition between two tables, I assumed it's based on sd_batch_headers_skey like in last query.
dbfiddle demo
with t as (
select h.batch_id, h.parent_batch_id, l.batch_submission_date bs_date
from headers h
join lines l on l.sd_batch_headers_skey = h.sd_batch_headers_skey
and l.batch_line_number = '1' )
select batch_id, parent_batch_id,
coalesce(bs_date, (select bs_date from t x where x.batch_id = t.parent_batch_id)) bs_date
from t
where batch_id = 12345;
You could use simpler syntax with connect by and level <= 2 but if in your data there are really rows containing same ids (99999, 99999) then we get cycle error.

How to append rows to result from SELECT query in SQL?

I have a query which gives me desired result. Column names are like this(which I am getting from the query):
RXID |DrName |SBOID |SBOName |RxHonoredDate |RxnHonoured |CallRecievedFrom |MobileNo
Now I have one table named 'SampleRepeat'. This have following columns
DrID | CallRecievedFrom | Mobile | SBOID |RxnHonoured
(Here we'll fetch DrName through DrID from table TblDr and SBOName through SBOID)
This is my query:
select G.RXID, NoOfRx, DrName,HospitalName,G.EmpCode AS SBOID ,TM_Name AS SBOName,CONVERT(DATETIME,H.CreatedDate) AS RxHonoredDate, DrSpeciality AS Speciality,
convert(DATETIME, G.CreatedDate) AS [RxGeneratedDate],COALESCE(H.rows, 0) AS RxnHonoured,
CallRecievedFrom,MobileNo ,G.HQ
from(
select RXID,SUM(RxGenerate) as NoOfRx, DrName,HospitalName,RX.EmpCode,TE.TM_Name, DrSpeciality,convert(DATE,RX.CreatedDate)as CreatedDate,TE.Territory AS HQ
from tbl_rx RX
left join tblEmployee TE on TE.TM_Emp_Id=RX.EmpCode
GROUP BY RX.EmpCode,RX.DrName,RX.HospitalName,RX.CreatedDate,RX.DrSpeciality,TE.TM_Name,RX.RXID,TE.Territory
)G
left join
( SELECT EmpCode,DrID,CreatedDate, SUM(MedToPCount) AS rows,CallRecievedFrom,MobileNo FROM tbl_MedicinToPatient WHERE Status = 'Delivered' GROUP BY EmpCode,DrID,CreatedDate,CallRecievedFrom,MobileNo
)H
on H.DrID=G.RXID ORDER BY TM_Name, H.CreatedDate ASC
I want to append this table values to end of query result and all other columns will be null.
I have tried Union all but no success. How do I do that? Any help would be much appreciated.
UNION with a calculated column or UNION ALL should work.
SELECT
*
FROM
(
SELECT
OrderID = 1
RXID,
DrName,
SBOID,
SBOName,
RxHonoredDate,
RxnHonoured,
CallRecievedFrom,
MobileNo
FROM
Query Q
UNION
SELECT
OrderID = 2
RXID = NULL,
DrName = DrID,
SBOID = NULL,
SBOName = SBOID,
RxHonoredDate = NULL,
RxnHonoured,
CallRecievedFrom,
MobileNo = Mobile
FROM
SampleRequest) AS X
ORDER BY
OrderID
Make sure that the order and data type of each column from both SELECT match.
SELECT
RXID,
DrName,
SBOID,
SBOName,
RxHonoredDate,
RxnHonoured,
CallRecievedFrom,
MobileNo
FROM
YourFirstTable AS T
UNION ALL
SELECT
RXID = NULL,
DrName = NULL,
SBOID = T.SBOID,
SBOName = NULL,
RxHonoredDate = NULL,
RxnHonoured = T.RxnHonoured,
CallRecievedFrom = T.CallRecievedFrom,
MobileNo = T.Mobile
FROM
YourSecondTable AS T

Distinct keyword not fetching results in Oracle

I have the following query where I unique records for patient_id, meaning patient_id should not be duplicate. Each time I try executing the query, seems like the DB hangs or it takes hours to execute, I'm not sure. I need my records to load quickly. Any quick resolution will be highly appreciated.
SELECT DISTINCT a.patient_id,
a.study_id,
a.procstep_id,
a.formdata_seq,
0,
(SELECT MAX(audit_id)
FROM audit_info
WHERE patient_id =a.patient_id
AND study_id = a.study_id
AND procstep_id = a.procstep_id
AND formdata_seq = a.formdata_seq
) AS data_session_id
FROM frm_rg_ps_rg a,
PATIENT_STUDY_STEP pss
WHERE ((SELECT COUNT(*)
FROM frm_rg_ps_rg b
WHERE a.patient_id = b.patient_id
AND a.formdata_seq = b.formdata_seq
AND a.psdate IS NOT NULL
AND b.psdate IS NOT NULL
AND a.psresult IS NOT NULL
AND b.psresult IS NOT NULL) = 1)
OR NOT EXISTS
(SELECT *
FROM frm_rg_ps_rg c
WHERE a.psdate IS NOT NULL
AND c.psdate IS NOT NULL
AND a.psresult IS NOT NULL
AND c.psresult IS NOT NULL
AND a.patient_id = c.patient_id
AND a.formdata_seq = c.formdata_seq
AND a.elemdata_seq! =c.elemdata_seq
AND a.psresult != c.psresult
AND ((SELECT (a.psdate - c.psdate) FROM dual)>=7
OR (SELECT (a.psdate - c.psdate) FROM dual) <=-7)
)
AND a.psresult IS NOT NULL
AND a.psdate IS NOT NULL;
For start, you have a cartesian product with PATIENT_STUDY_STEP (pss).
It is not connected to anything.
select *
from (select t.*
,count (*) over (partition by patient_id) as cnt
from frm_rg_ps_rg t
) t
where cnt = 1
;

How to find out non unique records?

SELECT TRD.PKG_ID||'_'||TRD_CONT_NBR||'_'||LEG.TRD_LEG_NBR||'_'|| TRD.TRD_ID||'_'||CF.CURR_CODE||'_'||cf.cflw_date||'_'||CF.CFLW_TYPE_CODE
||'_'||CF.CFLW_STATUS_CODE as Surrogate_key
, CF.EFF_DATE, TRD.PKG_ID, TRD_CONT_NBR, TRD.SRCE_TRD_ID
, LEG.TRD_LEG_NBR, TRD.TRD_ID, LEG.TRD_LEG_ID
, CF.CURR_CODE, cf.cflw_date, CF.TRD_CURR_CASH_FLOW_AMT
, CF.INT_RATE, cf.INT_RATE, CF.CFLW_TYPE_CODE, CF.CFLW_TYPE_GRP_CODE
, CF.CFLW_STATUS_CODE
from edw.extv_t_dim_trd TRD
, edw.extv_t_trade_leg LEG
, edw.extv_fact_cash_flow CF
where TRD.SRCE_TRD_ID = CF.SRCE_TRD_ID
and TRD.TRD_ID = CF.TRD_ID
and CF.SRCE_TRD_ID = LEG.SRCE_TRD_ID
and CF.TRD_LEG_ID = LEG.TRD_LEG_ID
and TRD.SRCE_SYS_CODE = 'WSS'
and cf.SRCE_SYS_CODE = 'WSS'
and leg.SRCE_SYS_CODE = 'WSS'
AND TRD.TRD_STATUS_CODE <> 'CANCELED'
AND LEG.INSTM_TYPE_CODE NOT IN ('FX', 'FX-OPTION')
AND TRD.TRD_ACTV_TO_DATE >= to_date('04/01/2013','mm/dd/yyyy')
and TRd.TECH_TRD_FLAG = 'N'
and cf.cflw_status_code = 'FINAL'
and TRD.ACTV_FLAG = 'Y'
and LEG.ACTV_FLAG = 'Y'
and cf.actv_flag ='Y'
With the above query, if add distinct in Surrogate_key I was able to find out the unique values but my problem is the overall record for the query is 3 million.. With distinct 2.5 million but I Would like to find non stop unique value of. 5 million. So how can I achieve that?
And one more in some cases we were not having primary key in the table so I use to form Surrogate_key . Even that was also contains some duplicate values. Future what kind of method if I need to use to avoid such problem.
Thanks,
Srini
I do not undestand all your problem, but assuming that you want to search duplicates of surrogate_key then maybe this script will be useful:
CREATE TABLE TEST(
Surrogate_key VARCHAR2(100));
INSERT INTO TEST VALUES('AAAA');
INSERT INTO TEST VALUES('ACAA');
INSERT INTO TEST VALUES('AAAA');
INSERT INTO TEST VALUES('AAAB');
INSERT INTO TEST VALUES('AAAA');
INSERT INTO TEST VALUES('ACAA');
/*HERE THE QUERY*/
SELECT T.Surrogate_key, COUNT(1) AS MATCHES
FROM TEST T
GROUP BY T.Surrogate_key
HAVING COUNT(1) > 1
You can try this here.
(EDITED 2013-07-15)
Assuming that your query works, then try this (with this you can find the repeated rows):
SELECT T.Surrogate_key, COUNT(1) AS MATCHES
FROM (
SELECT TRD.PKG_ID||'_'||TRD_CONT_NBR||'_'||LEG.TRD_LEG_NBR||'_'|| TRD.TRD_ID||'_'||CF.CURR_CODE||'_'||cf.cflw_date||'_'||CF.CFLW_TYPE_CODE
||'_'||CF.CFLW_STATUS_CODE as Surrogate_key
from edw.extv_t_dim_trd TRD
, edw.extv_t_trade_leg LEG
, edw.extv_fact_cash_flow CF
where TRD.SRCE_TRD_ID = CF.SRCE_TRD_ID
and TRD.TRD_ID = CF.TRD_ID
and CF.SRCE_TRD_ID = LEG.SRCE_TRD_ID
and CF.TRD_LEG_ID = LEG.TRD_LEG_ID
and TRD.SRCE_SYS_CODE = 'WSS'
and cf.SRCE_SYS_CODE = 'WSS'
and leg.SRCE_SYS_CODE = 'WSS'
AND TRD.TRD_STATUS_CODE <> 'CANCELED'
AND LEG.INSTM_TYPE_CODE NOT IN ('FX', 'FX-OPTION')
AND TRD.TRD_ACTV_TO_DATE >= to_date('04/01/2013','mm/dd/yyyy')
and TRd.TECH_TRD_FLAG = 'N'
and cf.cflw_status_code = 'FINAL'
and TRD.ACTV_FLAG = 'Y'
and LEG.ACTV_FLAG = 'Y'
and cf.actv_flag ='Y'
) T
GROUP BY T.Surrogate_key
HAVING COUNT(1) > 1