Oracle Join Two Queries With Distinct Answer - oracle

I need help in linking two tables together to bring back data as I need.
I have two queries:
The first is as follows:
SELECT
POI.PO_ID as PO_ID, SUM(POI.INV_QTY) AS INV_QTY, POI.INV_NUMBER,
PO.SUP_SUP_ID AS SUPPLIER
FROM TABLE1 POI, PUR_ORDS PO
WHERE POI.PO_ID = '56886' AND POI.PO_ID = PO.PO_ID
GROUP BY POI.PO_ID, POI.INV_NUMBER, PO.SUP_SUP_ID
ORDER BY POI.INV_NUMBER ASC
The Results of this query are as follows:
PO_ID|INV_QTY|INV_NUMBER|SUPPLIER
---------------------------------
56886| 105|INV1 |SUP1
56886| 106|INV2 |SUP1
The second query I have is this:
SELECT
DIL.PO_PO_ID, sum(DIL.ACPTD_QTY) as ACPTD_QTY,
DIL.DLVD_DLVY_NUMB AS DEL_NUM
FROM TABLE2 DIL
where DIL.PO_PO_ID = '56886'
GROUP BY PO_PO_ID, DIL.DLVD_DLVY_NUMB
order by del_num
The Results of this query are as follows:
PO_PO_ID|ACPTD_QTY|DEL_NUM
--------------------------
56886| 105| 1
56886| 106| 2
Now I am attempting to join the two tables, but I get multiple values appearing, using the following:
SELECT DISTINCT(PO_ID), INV_NUMBER, INV_QTY, SUPPLIER, ACPTD_QTY, DEL_NUM
FROM
(SELECT
SELECT POI.PO_ID as PO_ID, SUM(POI.INV_QTY) AS INV_QTY,
POI.INV_NUMBER, PO.SUP_SUP_ID AS SUPPLIER
FROM TABLE1 POI, PUR_ORDS PO
WHERE POI.PO_ID = '56886'
AND POI.PO_ID = PO.PO_ID
GROUP BY POI.PO_ID, POI.INV_NUMBER, PO.SUP_SUP_ID
ORDER BY POI.INV_NUMBER ASC) POINET
INNER JOIN
(SELECT DIL.PO_PO_ID, sum(DIL.ACPTD_QTY) as ACPTD_QTY,
DIL.DLVD_DLVY_NUMB AS DEL_NUM
FROM TABLE 2 DIL
where DIL.PO_PO_ID = '56886'
GROUP BY PO_PO_ID, DIL.DLVD_DLVY_NUMB
order by DEL_NUM) DILV
ON DILV.PO_PO_ID = POINET.PO_ID
GROUP BY PO_ID, INV_NUMBER, INV_QTY, SUPPLIER, ACPTD_QTY, DEL_NUM
ORDER BY INV_NUMBER
However the dataset I get is this:
PO_ID|INV_NUMBER |INV_QTY|SUPPLIER|ACPTD_QTY|DEL_NUM
-----------------------------------------------------
56886|K-101/2014-15| 105|SUP1 | 105| 1
56886|K-101/2014-15| 105|SUP1 | 106| 2
56886|K-107/2014-15| 106|SUP1 | 105| 1
56886|K-107/2014-15| 106|SUP1 | 106| 2
However I need it show the following:
PO_ID|INV_NUMBER |INV_QTY|SUPPLIER|ACPTD_QTY|DEL_NUM
------------------------------------------------------
56886|K-101/2014-15| 105|SUP1 | 105| 1
56886|K-107/2014-15| 106|SUP1 | 106| 2
What do I need to do, to tweak my query?
Any help would be much appreciated.

I think you just need to modify your join statement to join on both columns
ON DILV.PO_PO_ID = POINET.PO_ID
AND DILV.INV_QTY = POINET.ACPTD_QTY
Actually, you can probably leave out the PO_ID, because I it's the same in both subqueries:
i.e. Just do this (on the third last line):
ON DILV.INV_QTY = POINET.ACPTD_QTY

Related

How to group and uniqe each row with ORACLE?

Anyone please help me, how to uniqe each row
SELECT T3.ID_JS,T5.DIVISI_AREA,T4.NAME_METHODE_REPAIR, T1.URUTAN AS SORT, TO_DATE(T1.TIME_FINISHED_WORK,'DD/MM/YYYY') AS DATE_FINISHED
FROM TB_WORK T1
JOIN TB_INSPECTION T2 ON T1.ID_INSPECTION=T2.ID_INSPECTION
JOIN TB_JOBSHEET T3 ON T2.ID_JS = T3.ID_JS
JOIN TB_METHODE_REPAIR T4 ON T1.ID_METHODE_REPAIR=T4.ID_METHODE_REPAIR
JOIN TB_DIVISI T5 ON T1.ID_DIVISI=T5.ID_DIVISI
where t3.id_js=142414
GROUP BY T3.ID_JS,T5.DIVISI_AREA,T4.NAME_METHODE_REPAIR, T1.URUTAN,TO_DATE(T1.TIME_FINISHED_WORK,'DD/MM/YYYY')
ORDER BY T3.ID_JS, TO_DATE(T1.TIME_FINISHED_WORK,'DD/MM/YYYY') desc
[Result] (http://prntscr.com/sfpuuq)
Those rows are unique, so I'll guess: there are two rows with sort = 3 and you'd want to have only one. If that's so, regarding the fact that date value is the only thing that makes difference, a simple way is to use aggregate function (such as min or max). I used max, but you can change it if you want:
SELECT t3.id_js,
t5.divisi_area,
t4.name_methode_repair,
t1.urutan AS sort,
MAX (TO_DATE (t1.time_finished_work, 'DD/MM/YYYY')) AS date_finished
FROM tb_work t1
JOIN tb_inspection t2 ON t1.id_inspection = t2.id_inspection
JOIN tb_jobsheet t3 ON t2.id_js = t3.id_js
JOIN tb_methode_repair t4
ON t1.id_methode_repair = t4.id_methode_repair
JOIN tb_divisi t5 ON t1.id_divisi = t5.id_divisi
WHERE t3.id_js = 142414
GROUP BY t3.id_js,
t5.divisi_area,
t4.name_methode_repair,
t1.urutan
ORDER BY t3.id_js, date_finished DESC
You'd remove date column from GROUP BY; besides, if you wanted to select distinct rows, why didn't you apply select distinct instead of using group by? Result is the same, but - group by is generally used with aggregates, not to return distinct result.

Get STATUS from table by which join in oracle

I have a query for which based on CRNO I get the STATUS from another table. So the below query is
select a.crno, a.crno_date, a.state, a.status_rank from R4G_OSP.ENODEB a
Where a.crno is not null
and a.crno = 'R4G-MH-NLD-7718'
and a.status_rank is not null
order by 4 asc;
and STATUS table query is
select * from APP_WFM.WFM_CANDIDATE_STATUS where rank = 20
So, now I want to join the query and get the status in the first query. How should I do that
The sample data of both query is below
QUERY 1 SAMPLE DATA
QUERY 2 SAMPLE DATA
Please suggest how should I get the STATUS by joining it
You can use JOIN. Manual Here
select a.crno,
a.crno_date,
a.state,
a.status_rank,
APP_WFM.WFM_CANDIDATE_STATUS.STATUS
from R4G_OSP.ENODEB a
join APP_WFM.WFM_CANDIDATE_STATUS on APP_WFM.WFM_CANDIDATE_STATUS.RANK = a.status_rank
Where a.crno is not null
and a.crno = 'R4G-MH-NLD-7718'
and a.status_rank is not null
order by 4 asc;
If you want only rank 20 add AND a.status_rank = 20 before ORDER BY
Select a.crno,
a.crno_date,
a.state,
a.status_rank
from R4G_OSP.ENODEB a
join APP_WFM.WFM_CANDIDATE_STATUS on APP_WFM.WFM_CANDIDATE_STATUS.RANK = a.status_rank
and a.crno = 'R4G-MH-NLD-7718'
and a.status_rank is not null
order by 4 asc;
Based on the sample data of the table provided it is seen that the primary key relationship is set on WFM.WFM_CANDIDATE_STATUS.RANK and status_rank of another table so you can easily join between those columns

Only want to return rows that have duplicate unitid within group by unitid

I am working in SSRS querying against an oracle database.
So I have a data source and this report is supposed to find duplicate Work Orders based on multiple open workorders on a unique unitid. So I only want to show groups that have more then one entry as they are grouped by unitid.
SELECT
COMPSTSB.UNITID,
COMPSTSB.UNITTYPE,
ACTDEFN.ACTDESC,
ACTDEFN.ACTCODE,
HISTORY.WONO,
HISTORY.COMPFLAG,
HISTORY.ADDDTTM,
HISTORY.COMMENTS
FROM (IMSV7.COMPSTSB COMPSTSB INNER JOIN IMSV7.HISTORY HISTORY ON
COMPSTSB.COMPKEY=HISTORY.COMPKEY) INNER JOIN IMSV7.ACTDEFN ACTDEFN ON
HISTORY.ACTKEY=ACTDEFN.ACTKEY
WHERE HISTORY.COMPFLAG='Y' AND NOT (ACTDEFN.ACTCODE='DBR' OR ACTDEFN.ACTCODE='IN')
ORDER BY COMPSTSB.UNITTYPE, COMPSTSB.UNITID, HISTORY.ADDDTTM
Can anyone point me in the right direction? And yes before someone says this has been asked a million times, I did search. Point me to the million times and I will see if I feel they match my question. Ideally in the SQL I could make new column that returned a count of the unitid and I did attempt this but failed, and then I could filter on that column to remove any that only had one count. I really don't think this should be difficult but I have spent about 4 hours on it so far.
Thanks in advance!
Steven
If I understood your question right, the following should give you what's needed :
SELECT * FROM
(
SELECT
COMPSTSB.UNITID,
COMPSTSB.UNITTYPE,
ACTDEFN.ACTDESC,
ACTDEFN.ACTCODE,
HISTORY.WONO,
HISTORY.COMPFLAG,
HISTORY.ADDDTTM,
HISTORY.COMMENTS,
COUNT(1) OVER (PARTITION BY COMPSTSB.UNITID) AS numDups
FROM (IMSV7.COMPSTSB COMPSTSB INNER JOIN IMSV7.HISTORY HISTORY ON
COMPSTSB.COMPKEY=HISTORY.COMPKEY) INNER JOIN IMSV7.ACTDEFN ACTDEFN ON
HISTORY.ACTKEY=ACTDEFN.ACTKEY
WHERE HISTORY.COMPFLAG='Y' AND NOT (ACTDEFN.ACTCODE='DBR' OR ACTDEFN.ACTCODE='IN')
)a
WHERE a.numDups >1
ORDER BY COMPSTSB.UNITTYPE, COMPSTSB.UNITID, HISTORY.ADDDTTM
I expect you are concerned about having duplicate values of UNITID in the IMSV7.COMPSTSB table. If so adding this join to your query should enable ou to identify them:
JOIN (SELECT COMPSTSB.UNITID
FROM IMSV7.COMPSTSB
GROUP BY COMPSTSB.UNITID
HAVING COUNT(COMPSTSB.UNITID) > 1) dups
ON DUPS.UNITID = COMPSTSB.UNITID
JOIN IMSV7.HISTORY HISTORY
Here's the full query:
SELECT COMPSTSB.UNITID
, COMPSTSB.UNITTYPE
, ACTDEFN.ACTDESC
, ACTDEFN.ACTCODE
, HISTORY.WONO
, HISTORY.COMPFLAG
, HISTORY.ADDDTTM
, HISTORY.COMMENTS
FROM IMSV7.COMPSTSB COMPSTSB
JOIN (SELECT COMPSTSB.UNITID
FROM IMSV7.COMPSTSB
GROUP BY COMPSTSB.UNITID
HAVING COUNT(COMPSTSB.UNITID) > 1) dups
ON DUPS.UNITID = COMPSTSB.UNITID
JOIN IMSV7.HISTORY HISTORY
ON COMPSTSB.COMPKEY = HISTORY.COMPKEY
JOIN IMSV7.ACTDEFN ACTDEFN
ON HISTORY.ACTKEY = ACTDEFN.ACTKEY
WHERE HISTORY.COMPFLAG = 'Y'
AND ACTDEFN.ACTCODE NOT IN ('DBR','IN')
ORDER BY COMPSTSB.UNITTYPE
, COMPSTSB.UNITID
, HISTORY.ADDDTTM;
Since the above query didn't work you can try outer joins to similar sub queries on each of your tables and limit to only records where the outer joined table returns data. This will show you which tables in your query are cuasing your extra rows.:
SELECT COMPSTSB.UNITID
, COMPSTSB.UNITTYPE
, ACTDEFN.ACTDESC
, ACTDEFN.ACTCODE
, HISTORY.WONO
, HISTORY.COMPFLAG
, HISTORY.ADDDTTM
, HISTORY.COMMENTS
, DUPS.UNITID UNITID_DUP
, DUPS2.COMPKEY COMPKEY_DUP
, DUPS3.ACTKEY ACTKEY_DUP
FROM IMSV7.COMPSTSB COMPSTSB
JOIN IMSV7.HISTORY HISTORY
ON COMPSTSB.COMPKEY = HISTORY.COMPKEY
JOIN IMSV7.ACTDEFN ACTDEFN
ON HISTORY.ACTKEY = ACTDEFN.ACTKEY
LEFT JOIN (SELECT COMPSTSB.UNITID
FROM IMSV7.COMPSTSB
GROUP BY COMPSTSB.UNITID
HAVING COUNT(COMPSTSB.UNITID) > 1) dups
ON DUPS.UNITID = COMPSTSB.UNITID
LEFT JOIN (SELECT HISTORY.COMPKEY
FROM IMSV7.HISTORY
GROUP BY HISTORY.COMPKEY
HAVING COUNT(HISTORY.COMPKEY) > 1) dups2
ON DUPS.UNITID = COMPSTSB.UNITID
LEFT JOIN (SELECT ACTDEFN.ACTKEY
FROM IMSV7.ACTDEFN
GROUP BY ACTDEFN.ACTKEY
HAVING COUNT(ACTDEFN.ACTKEY) > 1) dups3
ON DUPS.UNITID = COMPSTSB.UNITID
WHERE HISTORY.COMPFLAG = 'Y'
AND ACTDEFN.ACTCODE NOT IN ('DBR','IN')
AND ( DUPS.UNITID IS NOT NULL OR
DUPS2.COMPKEY IS NOT NULL OR
DUPS3.ACTKEY IS NOT NULL)
ORDER BY COMPSTSB.UNITTYPE
, COMPSTSB.UNITID
, HISTORY.ADDDTTM;

How to update table1 field by using other table and function

I have two table and one function,
Table1 contains shop_code,batch_id,registry_id
shop_code| batch_id|registry_id
123 | 100 |12
124 | 100 |13
125 | 100 |12
Table2 contains shop_code,shop_name
shop_code| shop_name
123 | need to populate
124 | need to populate
125 | need to populate
Function1 take parameter registry_id from table1 and returns shop_name
Table2 shop_name is empty I want to populate against the shop_code.
I have tried my best but all effort is gone in vain.
It will be great if someone can help I am using Oracle.
I tried below code but giving error on from keyword
update TABLE2 set T2.SHOP_NAME = T.SHOP_NAME
from(
select GET_shop_name(t1.registry_id) as shop_name ,
t1.shop_code shop_code
from TABLE1 T1
) t where t.shop_code = t1.shop_code;
I am not entirely 100% sure if I got your question right, but I believe you want something like
update
table2 u
set
shop_name = (
select
get_shop_name(t1.batch_id)
from
table1 t1
where
t1.chop_code = u.shop_code
);
can you try this approach try to put inner query to get shop name value; I have not tested it but I think approach will work for you.
update TABLE2 T2
set T2.SHOP_NAME =
(select GET_shop_name(t1.batch_id, t1.shop_code) from table1 t1 wehre t1.shop_code = t2.shop_code)
where T2.shop_name is null
You want the MERGE statement.
Something like this might work:
MERGE INTO TABLE2 t2
USING (
SELECT GET_shop_name(t1.batch_id) AS shop_name ,
t1.shop_code shop_code
FROM TABLE1 T1 ) t1
ON (t2.shop_code = t1.shop_code)
WHEN MATCHED THEN
UPDATE SET t2.shop_name = t1.shop_name
;
You'll have to excuse if the exact code above doesn't work I don't have SQL Dev where I am right now for syntax details. :)

need help on sql query

am a newbie to Oracle/PL SQL.I've 2 tables A and B.
A has a column CustId,Age,Location and Date. Table B has 2 columns CustId,CustName.
What would be the sql query to show show CustName and Location for a given age?
Thanks.
your question "What would be the sql query to show show CustName and Location for a given age?" helps define your query pretty well:
SELECT CustName, Location
FROM TableA a
INNER JOIN TableB b
ON b.CustId = a.CustId
WHERE a.Age = #
All we need to do on top of that select for your specific fields is make sure to join the two tables on their common column (CustID).
Another option would be to avoid the WHERE statement:
SELECT CustName, Location
FROM TableB b
INNER JOIN TableA a
ON a.CustID = b.CustID
AND a.Age = #
you need join. something like
SELECT custname, location FROM a JOIN b ON a.custid = b.custid WHERE age = [age];

Resources