Joining multiple table in oracle 11g using sql query - oracle

i want all the column of treat_info table and corresponding fee of treatment table and equipment table.what is the sql query ?
The 3 tables image link is below
https://drive.google.com/file/d/0B3BFGC_k79UObHRjMGZpVXZwa3M/view?usp=sharing

I decided to use "LEFT JOIN" for not be sure if the fields are TREATMENT and EQUIPMENT are foreign keys.
So, you have the FEE value, if they exist.
select
T1.*
,T2.FEE as TREATMENT_FEE
,T3.FEE as EQUIP_FEE
from TREAT_INFO as T1
left join TREATMENT as T2 on T2.TREATMENT = T1.TREATMENT
left join EQUIPMENT as T3 on T3.EQUIPMENT = T1.EQUIPMENT

Related

Oracle Performance issues on using subquery in an "In" orperator

I have two query that looks close to the same but Oracle have very different performance.
Query A
Create Table T1 as Select * from FinalView1 where CustomerID in ('A0000001','A000002')
Query B
Create Table T1 as Select * from FinalView1 where CustomerID in (select distinct CustomerID from CriteriaTable)
The CriteriaTable have 800 rows but all belongs to Customer ID 'A0000001' and 'A000002'.
This means the subquery: "select distinct CustomerID from CriteriaTable" also only returns the same two elements('A0000001','A000002') as manually entered in query A
Following is the query under the FinalView1
create or replace view FinalView1_20200716 as
select
Customer_ID,
<Some columns>
from
Table1_20200716 T1
INNER join Table2_20200716 T2 on
T1.Invoice_number = T2.Invoice_number
and
T1.line_id = T2.line_id
left join Table3_20200716 T3 on
T3.id = T1.Customer_ID
left join Table4_20200716 T4 on
T4.Shipping_ID = T1.Shipping_ID
left join Table5_20200716 Table5 on
Table5.Invoice_ID = T1.Invoice_ID
left join Table6_20200716 T6 on
T6.Shipping_ID = T4.Shipping_ID
left join First_Order first on
first.Shipping_ID = T1.Shipping_ID
;
Table1_20200716,Table2_20200716,Table3_20200716,Table4_20200716,Table5_20200716,Table6_20200716 are views to the corresponding table with temporal validity feature. For example
The query under Table1_20200716
Create or replace view Table1_20200716 as
select
*
from Table1 as for period of to_date('20200716,'yyyymmdd')
However table "First_Order" is just a normal table as
Following is the performance for both queries (According to explain plan):
Query A:
Cardinality: 102
Cost : 204
Total Runtime: 5 secs max
Query B:
Cardinality:27921981
Cost: 14846
Total Runtime:20 mins until user cancelled
All tables are indexed using those columns that used to join against other tables in the FinalView1. According to the explain plan, they have all been used except for the FirstOrder table.
Query A used uniquue index on the FirstOrder Table while Query B performed a full scan.
For query B, I was expecting the Oracle will firstly query the sub-query get the result into the in operator, before executing the main query and therefore should only have minor impact to the performance.
Thanks in advance!
As mentioned from my comment 2 days ago. Someone have actually posted the solution and then have it removed while the answer actually work. After waiting for 2 days the So I designed to post that solution.
That solution suggested that the performance was slow down by the "in" operator. and suggested me to replace it with an inner join
Create Table T1 as
Select
FV.*
from
FinalView1 FV
inner join (
select distinct
CustomerID
from
CriteriaTable
) CT on CT.customerid = FV.customerID;
Result from explain plan was worse then before:
Cardinality:28364465 (from 27921981)
Cost: 15060 (from 14846)
However, it only takes 17 secs. Which is very good!

Oracle query select data in multi tables

I have 2 tables.
This is tableA
(invoice,D/O, cost..) and
Table B
(D/O, GRN, Qty)
Now how to use query to show table A include GRN,Qty
See
You need a LEFT OUTER JOIN to retrieve all the records from table A with matched records from table B.
Guessing at the join criteria because your question doesn't say what they are:
select a.*
, b.grn
, b.grn_line
, b.qty_grn
from a
left outer join b
on a.do = b.do
and a.do_line = b.do_line
and a.invoice_line = b.grn_line

Oracle 11g - Selecting multiple records from a table column

I was just wondering how you select multiple records from a table column. Please see below the query.
SELECT DISTINCT DEPARTMENT_NAME, CITY, COUNTRY_NAME
FROM OEHR_DEPARTMENTS
NATURAL JOIN OEHR_EMPLOYEES
NATURAL JOIN OEHR_LOCATIONS
NATURAL JOIN OEHR_COUNTRIES
WHERE JOB_ID = 'SA_MAN' AND JOB_ID = 'SA_REP'
;
Basically, I want to be able to select records from the table column I have, however when you use AND it only displays SA_MAN and not SA_REP. I have also tried to use OR and it displays no rows selected. How would I actually be able to select both Job ID's without it just displaying one or the other.
Sorry this may sound like a stupid question (and probably not worded right), but I am pretty new to Oracle 11g SQL.
For your own comfort while debugging, I suggest you to use inner joins instead of natual joins.
That where clause is confusing, if not utterly wrong, because you don't make clear which tables' JOB_ID should be filtered. Use inner joins, give aliases to tables, and refer to those aliases in the where clause.
select distinct DEPARTMENT_NAME, CITY, COUNTRY_NAME
from OEHR_DEPARTMENTS t1
join OEHR_EMPLOYEES t2
on ...
join OEHR_LOCATIONS t3
on ...
join OEHR_COUNTRIES t4
on ...
where tn.JOB_ID = 'SA_MAN' AND tm.JOB_ID = 'SA_REP'
After rephrasing your query somehow like this, you'll have a clearer view on the logical operator you'll have to use in the where clause, which I bet will be an OR.
EDIT (after more details were given)
To list the departments that employ staff with both 'SA_MAN' and 'SA_REP' job_id, you have to join the departments table with the employees twice, once with the filter job_id='SA_MAN' and once with job_id='SA_REP'
select distinct DEPARTMENT_NAME, CITY, COUNTRY_NAME
from OEHR_DEPARTMENTS t1
join OEHR_EMPLOYEES t2
on t1.department_id = t2.department_id --guessing column names
join OEHR_EMPLOYEES t3
on t1.department_id = t3.department_id --guessing column names
join OEHR_LOCATIONS t4
on t1.location_id = t4.location_id --guessing column names
join OEHR_COUNTRIES t5
on t4.country_id = t5.country_id --guessing column names
where t2.job_id = 'SA_MAN' and t3.job_id = 'SA_REP'
order by 1, 2, 3

Order of columns returned in SQL query (With table join)

I am wondering what determines the order of columns returned in a SQL query.
For example, SELECT * FROM SOMETABLE;
SQ_ID |BUS_TYPE |VOIP |LOCAL_PHONE
--------|-----------|---------|-------------
SQ000001|Business |Y |N
I am guessing the attribute COLUMN_ID determines this. In the case of a table join, for example, SELECT * FROM SOMETABLE LEFT JOIN OTHERTABLE USING (SOME_COL); how is the order now determine.
The order of columns in SELECT * FROM some_table is determined by the column_id of each column, as seen in USER_TAB_COLUMNS.
The order of columns in SELECT * FROM some_table JOIN other_table is all the columns for each table starting with the leftmost table after the FROM clause. In other words, this ...
SELECT * FROM some_table JOIN other_table
... is equivalent to this ...
SELECT some_table.*, other_table.* FROM some_table JOIN other_table
Changing that inner join to LEFT JOIN or RIGHT JOIN won't change the projection.
This is, of course, theoretical. We should never use select * in production code. Explicit column declarations, with table aliases when joining, are always safer. Apart from better expression of intent, explicit projections protect our code from future changes to the tables such as adding a LOB column or a column name which creates ambiguity with a joined table's column.
You can list the order of the colums in the Select statement:
SELECT SOME_COL, SOME_OTHER_COL
FROM SOMETABLE LEFT JOIN OTHERTABLE USING (SOME_COL)
But you also speak of the ID influencing the order and of ordering in general. So I think you could also be looking for ORDER BY to order the rows:
SELECT *
FROM SOMETABLE LEFT JOIN OTHERTABLE USING (SOME_COL)
ORDER BY SOME_COL
What also comes quite handy in this case is the use of aliases. Especally when both tables have coloums with the same name:
SELECT s.some_col, o.some_col
FROM SOMETABLE s LEFT JOIN OTHERTABLE o ON(o.id = s.id)
ORDER BY o.SOME_COL
I use the ON JOIN syntax in this case, because i find this more intuive when using aliases but it should also work with USING.

Inner or Outer left Join

I'm having difficulty modifying a script for this situation and wondering if someone maybe able to help:
I have an address table and a phone table both sharing the same column called id_number. So id_number = 2 on both tables refers to the same entity. Address and phone information used to be stored in one table (the address table) but it is now split into address and phone tables since we moved to Oracle 11g.
There is a 3rd table called both_ids. This table also has an id_number column in addition to an other_ids column storing SSN and some other ids.
Before the table was split into address and phone tables, I had this script:
(Written in Sybase)
INSERT INTO sometable_3 (
SELECT a.id_number, a.other_id,
NVL(a1.addr_type_code,0) home_addr_type_code,
NVL(a1.addr_status_code,0) home_addr_status_code,
NVL(a1.addr_pref_ind,0) home_addr_pref_ind,
NVL(a1.street1,0) home_street1,
NVL(a1.street2,0) home_street2,
NVL(a1.street3,0) home_street3,
NVL(a1.city,0) home_city,
NVL(a1.state_code,0) home_state_code,
NVL(a1.zipcode,0) home_zipcode,
NVL(a1.zip_suffix,0) home_zip_suffix,
NVL(a1.telephone_status_code,0) home_phone_status,
NVL(a1.area_code,0) home_area_code,
NVL(a1.telephone_number,0) home_phone_number,
NVL(a1.extension,0) home_phone_extension,
NVL(a1.date_modified,'') home_date_modified
FROM both_ids a, address a1
WHERE a.id_number = a1.id_number(+)
AND a1.addr_type_code = 'H');
Now that we moved to Oracle 11g, the address and phone information are split.
How can I modify the above script to generate the same result in Oracle 11g?
Do I have to first do INNER JOIN between address and phone tables and then do a LEFT OUTER JOIN to both_ids?
I tried the following and it did not work:
Insert Into..
select ...
FROM a1. address
INNER JOIN t.Phone ON a1.id_number = t.id_number
LEFT OUTER JOIN both_ids a ON a.id_number = a1.id_number
WHERE a1.adrr_type_code = 'H'
There is a syntax error in your query. You wrote in comment below that your query is:
..
FROM address a1 JOIN telephone t ON a1.id_number = t.id_number
AND RIGHT OUTER JOIN tt_gl_both_ids a ON a.id_number = a1.id_number
WHERE
..
Throw out AND and it will work. Also, replace right outer join with left outer join, since that's what you're trying to achieve (again, based on comments you wrote).

Resources