FULL OUTER JOIN in oracle - sql

I just noticed FULL OUTER JOIN is not working in Oracle.
Other queries work fine but when I fire the query with Full outer join, it takes time and gets disconnected throwing the error.
ORA-03113: end-of-file on communication channel
RIGHT OUTER JOIN and LEFT OUTER JOIN works fine.
What can be alternative for the query below where I am using full outer join to get all records ?
select * from
(
select
FTM_OFFICE_ID,
NVL(SUM(FTD_NRS_AMOUNT),0) as TOTAL
from FMS_TRANS_DTL
inner join FMS_TRANS_MST ON FMS_TRANS_MST.FTM_TRANS_MST_ID = FMS_TRANS_DTL.FTD_TRANS_MST_ID
inner join FMS_FC_VOUCHER_CONFIG ON FMS_FC_VOUCHER_CONFIG.FFVC_VOUCHER_ID = FMS_TRANS_MST.FTM_VOUCHER_ID
where FFVC_ACCOUNT_TYPE = 3 and FTM_FISCAL_YEAR='2066/67'
and FTD_ACC_ID in (select distinct FDP_DHARAUTI_C_ACC_ID from FMS_DHARAUTI_PARAMETER where FDP_FISCAL_YEAR='2066/67' )
/*and FTD_ACC_ID in (591)*/
group by FTM_OFFICE_ID
) T1
full outer join
(
select
FTM_OFFICE_ID,
NVL(SUM(FTD_NRS_AMOUNT),0) as TOTAL
from FMS_TRANS_DTL
inner join FMS_TRANS_MST ON FMS_TRANS_MST.FTM_TRANS_MST_ID = FMS_TRANS_DTL.FTD_TRANS_MST_ID
inner join FMS_FC_VOUCHER_CONFIG ON FMS_FC_VOUCHER_CONFIG.FFVC_VOUCHER_ID = FMS_TRANS_MST.FTM_VOUCHER_ID
where FFVC_ACCOUNT_TYPE = 3 and FTM_FISCAL_YEAR='2066/67'
/*and FTD_ACC_ID in (592)*/
and FTD_ACC_ID in
(select distinct FDP_DHARAUTI_L_ACC_ID from FMS_DHARAUTI_PARAMETER where FDP_FISCAL_YEAR='2066/67' )
group by FTM_OFFICE_ID
) T2
on T1.FTM_OFFICE_ID=T2.FTM_OFFICE_ID
/*
The no. of rows that T1 can have can be different that no. of rows T2 can have.
Its not necessary any OFFICE_ID must have amount under any FTD_ACC_ID.
*/
Just noticed that if I remove the sub query in condition for FTD_ACC_ID, the query runs perfectly. Why ?

workaround based on your query + followup comments is:
alter session set "_optimizer_cost_based_transformation"=off;
eg:
SQL> alter session set "_optimizer_cost_based_transformation"=off;
Session altered.
or in the sql as a hint
/*+ opt_param('_optimizer_cost_based_transformation', 'off')
eg
select /*+ opt_param('_optimizer_cost_based_transformation', 'off') */ * from
(
select FTM_OFFICE_ID,
you're possibly hitting bug:
BUG 4204383: ORA-7445[KKQTNLOCBK] USING QUERY WITH SUBQUERY AND FULL OUTER JOIN
which has patched available only on 10.2.0.2 onwards (fixed fully in 10.2.0.4).

FULL OUTER JOIN is supported just fine in Oracle.
The error you're experiencing sounds like an Oracle bug, or possible some form of corruption. You should find an error recorded in the alert.log whenever an ORA-03113 occurs.
Typically if you receive this error it's because the background oracle system process for that session has died (which is almost always due to an Oracle internal error).
This is a problem for your friendly local DBA.

If indeed (for whatever reason) a full outer join doesn't work for you, use
-- all rows present in both t1 and t2
select * from t1 inner join t2
union all
-- all rows present in t1 but not in t2
select * from t1 left outer join t2 where t2.pk is null
union all
-- all rows present in t2 but not in t1
select * from t1 right outer join t2 where t1.pk is null
instead of
select * from t1 full outer join t2
This will return the same result.

You can try this query:
SELECT
FTM_OFFICE_ID,
NVL(SUM(FTD_NRS_AMOUNT),0) AS TOTAL
FROM FMS_TRANS_DTL
INNER JOIN FMS_TRANS_MST ON FMS_TRANS_MST.FTM_TRANS_MST_ID = FMS_TRANS_DTL.FTD_TRANS_MST_ID
INNER JOIN FMS_FC_VOUCHER_CONFIG ON FMS_FC_VOUCHER_CONFIG.FFVC_VOUCHER_ID = FMS_TRANS_MST.FTM_VOUCHER_ID
WHERE FFVC_ACCOUNT_TYPE = 3 AND FTM_FISCAL_YEAR='2066/67'
AND FTD_ACC_ID IN (
SELECT DISTINCT FDP_DHARAUTI_C_ACC_ID FROM FMS_DHARAUTI_PARAMETER WHERE FDP_FISCAL_YEAR='2066/67'
UNION
SELECT DISTINCT FDP_DHARAUTI_L_ACC_ID FROM FMS_DHARAUTI_PARAMETER WHERE FDP_FISCAL_YEAR='2066/67'
)
GROUP BY FTM_OFFICE_ID

Looks like the only thing different is separate totals for FTD_ACC_ID values of 105 and 110. One approach would be to use CASE statements to total those separately.
select
FTM_OFFICE_ID,
NVL(SUM(CASE FTD_ACC_ID WHEN 105 THEN FTD_NRS_AMOUNT ELSE 0 END),0) as TOTAL_105,
NVL(SUM(CASE FTD_ACC_ID WHEN 110 THEN FTD_NRS_AMOUNT ELSE 0 END),0) as TOTAL_110,
from FMS_TRANS_DTL
inner join FMS_TRANS_MST ON FMS_TRANS_MST.FTM_TRANS_MST_ID = FMS_TRANS_DTL.FTD_TRANS_MST_ID
inner join FMS_FC_VOUCHER_CONFIG ON FMS_FC_VOUCHER_CONFIG.FFVC_VOUCHER_ID = FMS_TRANS_MST.FTM_VOUCHER_ID
where FFVC_ACCOUNT_TYPE = 3 and FTM_FISCAL_YEAR='2066/67'
and FTD_ACC_ID in (105,110)
group by FTM_OFFICE_ID

Use UNION instead of FULL OUTER JOIN in your query like this
select * from
(
select
FTM_OFFICE_ID,
NVL(SUM(FTD_NRS_AMOUNT),0) as TOTAL
from FMS_TRANS_DTL
inner join FMS_TRANS_MST ON FMS_TRANS_MST.FTM_TRANS_MST_ID = FMS_TRANS_DTL.FTD_TRANS_MST_ID
inner join FMS_FC_VOUCHER_CONFIG ON FMS_FC_VOUCHER_CONFIG.FFVC_VOUCHER_ID = FMS_TRANS_MST.FTM_VOUCHER_ID
where FFVC_ACCOUNT_TYPE = 3 and FTM_FISCAL_YEAR='2066/67'
and FTD_ACC_ID = 105
group by FTM_OFFICE_ID ) T1 union (select FTM_OFFICE_ID,
NVL(SUM(FTD_NRS_AMOUNT),0) as TOTAL
from FMS_TRANS_DTL
inner join FMS_TRANS_MST ON FMS_TRANS_MST.FTM_TRANS_MST_ID = FMS_TRANS_DTL.FTD_TRANS_MST_ID
inner join FMS_FC_VOUCHER_CONFIG ON FMS_FC_VOUCHER_CONFIG.FFVC_VOUCHER_ID = FMS_TRANS_MST.FTM_VOUCHER_ID
where FFVC_ACCOUNT_TYPE = 3 and FTM_FISCAL_YEAR='2066/67'
and FTD_ACC_ID = 110
group by FTM_OFFICE_ID )T2

Related

Optimising SQL Query with multiple joins, reducing query speed

I'd like some advice on how to optimize the code below. I have attached the relationship of table above, any feedback or direction you could point me to will be appreciated.
The current query seems to be taking quite long to process.
SELECT CUSTINVOICETRANS.INVENTTRANSID, CUSTINVOICETRANS.INVOICEDATE, CUSTINVOICETRANS.INVOICEID, CUSTINVOICETRANS.ITEMID, CUSTINVOICETRANS.LINEAMOUNT, CUSTINVOICETRANS.LINEAMOUNTTAX, CUSTINVOICETRANS.ORIGSALESID, CUSTINVOICETRANS.QTY, CUSTINVOICETRANS.SUMLINEDISC, CUSTINVOICEJOUR.CUSTGROUP, CUSTINVOICEJOUR.INVOICEACCOUNT, CUSTINVOICEJOUR.SALESID, SALESTABLE.VCORDERMODE, SALESTABLE.VCORDERRT, VCSALESTABLEINFO.RCVDATE, VCSALESTABLEINFO.SHPCSTMCD, VCSALESTABLEINFO.VCORIGINALINVOICEDATE, SALESLINE.DATAAREADID, SALESLINE.INVENTTRANSID, VCSALESLINEINFO.RLLINEID
FROM CUSTINVOICETRANS
INNER JOIN CUSTINVOICEJOUR
ON CUSTINVOICETRANS.INVOICEID = CUSTINVOICEJOUR.INVOICEID
AND CUSTINVOICETRANS.INVOICEDATE = CUSTINVOICEJOUR.INVOICEDATE
AND CUSTINVOICETRANS.INVOICEDATE>=DATEADD(DAY,-7,GETDATE())
INNER JOIN SALESTABLE
ON CUSTINVOICETRANS.ORIGSALESID = SALESTABLE.SALESID
AND CUSTINVOICETRANS.INVOICEDATE>=DATEADD(DAY,-7,GETDATE())
INNER JOIN VCSALESTABLEINFO
ON CUSTINVOICETRANS.ORIGSALESID = VCSALESTABLEINFO.SALESID
AND CUSTINVOICETRANS.INVOICEDATE>=DATEADD(DAY,-7,GETDATE())
INNER JOIN SALESLINE
ON CUSTINVOICETRANS.ORIGSALESID = SALESLINE.SALESID
AND CUSTINVOICETRANS.INVOICEDATE>=DATEADD(DAY,-7,GETDATE())
INNER JOIN VCSALESLINEINFO
ON SALESLINE.INVENTTRANSID = VCSALESLINEINFO.INVENTTRANSID```
You can use cte to filter first your customer invoice transactions before joining other tables.
WITH cte as
(
SELECT INVENTTRANSID, INVOICEDATE, INVOICEID
, ITEMID, LINEAMOUNT, LINEAMOUNTTAX
, ORIGSALESID, QTY, SUMLINEDISC
FROM CUSTINVOICETRANS WHERE INVOICEDATE>=DATEADD(DAY,-7,GETDATE())
)
SELECT t1.*, t2.CUSTGROUP, t2.INVOICEACCOUNT, t2.SALESID
, t3.VCORDERMODE, t3.VCORDERRT
, t4.RCVDATE, t4.SHPCSTMCD, t4.VCORIGINALINVOICEDATE
, t5.DATAAREADID, t5.INVENTTRANSID
, t6.RLLINEID
FROM cte t1
INNER JOIN CUSTINVOICEJOUR t2 on t2.INVOICEID = t1.INVOICEID and t1.INVOICEDATE = t2.INVOICEDATE
INNER JOIN SALESTABLE t3 on t3.SALESID = t1.ORIGSALESID
INNER JOIN VCSALESTABLEINFO t4 on t4.SALESID = t1.ORIGSALESID
INNER JOIN SALESLINE t5 on t5.SALESID = t1.ORIGSALESID
INNER JOIN VCSALESLINEINFO t6 on t6.INVENTTRANSID = t5.INVENTTRANSID
Pull the first INNER JOIN outcome to a dataframe / temp table t1.
Join the same with second INNER Join dataset.
pull the data into another temp table / data frame.
Drop the temp table t1 at the end.
Follow the step for for subsequesnt joins.
Regards

SQL Server: JOIN two different queries

sql-server does not have USING function. To join two different tables with multiple select statements we use 'ON' table1.ID = Table2.ID
SELECT *
FROM
(SELECT M.ID as MAPID, M.Name, Avg(Distance) 'Avg Road length', Max(Distance)'Max Length'
FROM MAP
inner join ROAD R on M.ID = R.MapID
GROUP BY M.ID, M.Name) T1
left join
SELECT *
FROM
(SELECT select R.MapID as MAPID, R.IDFrom, R.IDTo
from ROAD R
group by R.MapID, R.IDFrom, R.IDTo) T2 ON T1.MAPID = T2.MAPID
-- using (MAPID); (wrong)
Replace
USING (MAPID)
with
ON t1.mapid = t2.mapid

Query for records count from shown rows

select lsd.lsd ,count(reading.infrastructure_id),type.infrastructure_type from public.cpreading_lsd lsd
left join cpreading_infrastructure infra on lsd.id = infra.lsd_id
left join public.cpreading_infrastructure_type type on type.id = infra.infrastructure_type_id
left join cpreading_cp_reading_entry reading on infra.id = reading.infrastructure_id
group by lsd.lsd,type.infrastructure_type
Make the query as an in-line view and select count(*) from the in-line view
Eg:
select count(*) from(
select lsd.lsd
,count(reading.infrastructure_id)
,type.infrastructure_type
from public.cpreading_lsd lsd
left join cpreading_infrastructure infra on lsd.id = infra.lsd_id
left join public.cpreading_infrastructure_type type on type.id = infra.infrastructure_type_id
left join cpreading_cp_reading_entry reading on infra.id = reading.infrastructure_id
group by lsd.lsd,type.infrastructure_type
)x

Correct Syntax When Limiting Results in Sybase SQL Statement Query

I am trying to put a limit on my Sybase SELECT statement query, but I keep getting syntax errors. I've tried using both limit and SELECT * TOP 10, but neither seems to work. This is my SELECT statement code:
SELECT top 10 *
// column params
FROM claims c
LEFT OUTER JOIN claims_transaction as ct
ON ct.claim_id = c.id
LEFT OUTER JOIN claims_batch_listings cb
ON cb.batch_listing = c.batchl
LEFT OUTER JOIN notes_details d
ON d.id_number = c.notes_detail_id
LEFT OUTER JOIN individual_ins_xref px
ON px.pt_id = c.ind_id
AND px.ins_id = c.ins_id
LEFT OUTER JOIN individuals ind
ON ind.id_number = c.ind_id
LEFT OUTER JOIN sections sec
ON ind.sec_id = sec.id_number
LEFT OUTER JOIN contract_items cont
ON c.contract_id = cont.contract_id
WHERE ( d.date_of_visit >= px.coverage_start AND d.date_of_visit <= px.coverage_end )
AND visit_type <> 'No Visit'
ORDER BY c.datetimecreated;
The * is wrong. Just lose it and you should be OK:
SELECT top 10 -- * removed here
c.claim_problem as problem,
-- etc.

Using an Inner join select statement

I am fairly new to SQL. I have created an inner join between 2 tables and further created some where clauses to pull out the appropriate data. As I understand it I have used an inner join to connect 2 tables. What I am trying to do now is connect my resultant select query to another table. How would I do this?
SELECT
t.[Type]
from [MITS].[dbo].[monster] t
inner join (
SELECT [MITS].[dbo].[BROKERTABLE].[BrokerID]
,[MITS].[dbo].[CustomerRates].[MPAN_ID]
,[MITS].[dbo].[BROKERTABLE].[Commission_Rate]
,[MITS].[dbo].[BROKERTABLE].[Rate_From]
,[MITS].[dbo].[BROKERTABLE].[Rate_To]
,[MITS].[dbo].[CustomerRates].[From_Date]
,[MITS].[dbo].[CustomerRates].[To_Date]
from [MITS].[dbo].[CustomerRates]
Inner Join [MITS].[dbo].[BROKERTABLE]
on [MITS].[dbo].[BROKERTABLE].[MPAN_ID] =
[MITS].[dbo].[CustomerRates].[MPAN_ID]
where
[MITS].[dbo].[CustomerRates].[To_Date] <=
[MITS].[dbo].[BROKERTABLE].[Rate_To]
and
convert(datetime,'01/11/2015',103)
between convert(datetime,[MITS].[dbo].[CustomerRates].[From_Date],103)
and convert(datetime,[MITS].[dbo].[CustomerRates].[To_Date],103)
) d on t.MITID = d.MPAT_ID
Add extra table into existing query: guess 1
select *
from atable a
inner join btable b on a.somecol = b.somecol
inner join extra_table t on a.somecol = t.somecol and b.somecol = t.somecol2
Add existing query to a table, method 1
select *
from extra_table t
inner join (
your existing query here
) d on t.somecol = d.somecol
Add existing query to a table, method 2
select *
from (
your existing query here
) d
inner join extra_table t on d.somecol = t.somecol