Outer join that give no result
Hi everybody
Here are the scripts
CREATE TABLE dem_comment (
COMMENTID VARCHAR2(50 BYTE) NOT NULL,
PARENTID VARCHAR2(50 BYTE) NOT NULL,
DEM_DATE_CREATION_MEMO date)
CREATE TABLE demand(
NUM_PCE VARCHAR2(14 BYTE) NOT NULL,
NUM_DEMANDE VARCHAR2(8 BYTE)
insert into dem_comment VALUES (1,'12345ABCDEF',to_date('17/08/2012 10:18:34','DD/mm/YYyy HH:MI:SS'))
insert into demand values('12345','ABCDEF')
And the following is the request that have the problem
select dem.NUM_PCE, memo.parentid
from demand dem, dem_comment memo
where CONCAT(dem.NUM_PCE,dem.NUM_DEMANDE) = memo.parentId (+)
and memo.DEM_DATE_CREATION_MEMO = (select MAX(DEM_DATE_CREATION_MEMO)
FROM dem_comment memo
WHERE memo.parentId = CONCAT(dem.NUM_PCE,dem.NUM_DEMANDE))
And the result is the one i m waiting for
NUMPCE | PARENTID
12345 | 12345ABCDEF
but when i delete the record from dem_comment, (because of the outer join) i m supposed to have something like
NUMPCE | PARENTID
12345 |
but the result is that, no record
NUMPCE | PARENTID
The outer join seems to not work
Thank you for your help
UW (Germany) wrote:
Sorry, I was too fast and did not notice the nested select. Try this:
select dem.NUM_PCE, memo.parentid
from demand dem
left outer join dem_comment memo on CONCAT(dem.NUM_PCE,dem.NUM_DEMANDE) = memo.parentId
where memo.DEM_DATE_CREATION_MEMO is null
or memo.DEM_DATE_CREATION_MEMO = (select MAX(DEM_DATE_CREATION_MEMO)
FROM dem_comment memo
WHERE memo.parentId = CONCAT(dem.NUM_PCE,dem.NUM_DEMANDE));
It is an left outer join, so the predicate on the left table belongs in the on clause
from demand dem
left outer join dem_comment memo
on CONCAT(dem.NUM_PCE,dem.NUM_DEMANDE) = memo.parentId
and
memo.DEM_DATE_CREATION_MEMO = (select MAX(DEM_DATE_CREATION_MEMO)
FROM dem_comment memo
WHERE memo.parentId = CONCAT(dem.NUM_PCE,dem.NUM_DEMANDE))
Similar Messages
-
Old outer join syntax produces different results from new syntax!
I have inherited a query that uses the old outer join syntax but that is yielding correct results. When I translate it to the new outer join syntax, I get the results I expect, but they are not correct! And I don't understand why the old syntax produces the results it produces. Bottom line: I want the results I'm getting from the old syntax, but I need it in the new syntax (I'm putting it into Reporting Services, and RS automatically converts old syntax to new).
Here's the query with the old outer join syntax that is working correctly:
Code Snippet
SELECT TE = COUNT(DISTINCT T1.ID),
UE = COUNT(DISTINCT T2.ID),
PE = CONVERT(MONEY, COUNT(DISTINCT T2.ID)) /
CONVERT(MONEY,COUNT(DISTINCT T1.ID))
FROM TABLE T1, TABLE T2
WHERE T1 *= T2
In this query, much to my surprise, TE <> UE and PE <> 1. However, TE, UE, and PE seem to be accurate!
Here's the query with the new outer join syntax that is working but not producing the results I need:
Code Snippet
SELECT TE = COUNT(DISTINCT T1.ID),
UE = COUNT(DISTINCT T2.ID),
PE = CONVERT(MONEY, COUNT(DISTINCT T2.ID)) /
CONVERT(MONEY,COUNT(DISTINCT T1.ID))
FROM TABLE T1 LEFT OUTER JOIN TABLE T2 ON T1.ID = T2.ID
Though not producing the results I need, it is producing what would be expected: TE = UE and PE = 1.
My questions:
1) Can someone who is familiar enough with the old syntax please help me understand why TE <> UE and PE <> 1 in the first query?
2) Can someone please tell me how to properly translate the first query to the new syntax so that it continues to produce the results in the first query?
Thank you very much.How can we reproduce the issue?
Code Snippet
USE [master]
GO
EXEC sp_dbcmptlevel Northwind, 80
GO
USE [Northwind]
GO
SELECT
TE
= COUNT(DISTINCT T1.OrderID),
UE = COUNT(DISTINCT T2.OrderID),
PE = CONVERT(MONEY, COUNT(DISTINCT T2.OrderID)) /
CONVERT(MONEY,COUNT(DISTINCT T1.OrderID))
FROM
dbo
.Orders T1, dbo.Orders T2
WHERE
T1
.OrderID *= T2.OrderID
SELECT
TE
= COUNT(DISTINCT T1.OrderID),
UE = COUNT(DISTINCT T2.OrderID),
PE = CONVERT(MONEY, COUNT(DISTINCT T2.OrderID)) /
CONVERT(MONEY,COUNT(DISTINCT T1.OrderID))
FROM
dbo
.Orders T1
LEFT OUTER JOIN
dbo.Orders T2
ON T1.OrderID = T2.OrderID
GO
EXEC sp_dbcmptlevel Northwind, 90
GO
Result:
TE
UE
PE
830
830
1.00
TE
UE
PE
830
830
1.00
As you can see, I am getting same results.
AMB -
How to use outer join to display the results
I want to develop a report in which the column sequence will be as follows:
1)Item_code
2)Item_name
3)Stock
4)Pending
5)Re-order Level
6)Item_reorder_qty
I had written the query, but the problem is all the products does not get displayed. The products are more than 700. But after running the query, only 364 gets displayed.
How i can make use of outer join in the following statements :
AND ITEM_CODE = LCS_ITEM_CODE
AND ITEM_CODE = PI_ITEM_CODE
AND LCS_ITEM_CODE = PI_ITEM_CODE
in the below given query to solve this.
SELECT
ITEM_CODE,
ITEM_NAME,
((LCS_STK_QTY_BU + LCS_RCVD_QTY_BU - LCS_ISSD_QTY_BU- LCS_REJECT_QTY_BU)/IU_MAX_LOOSE_1)STK ,
SUM(TO_NUMBER(PI_QTY||'.'||PI_QTY_LS) - (PI_GI_QTY_BU/IU_CONV_FACTOR/IU_MAX_LOOSE_1))PNDG,
ITEM_RORD_LVL,
ITEM_RORD_QTY
FROM
OM_ITEM,
OM_ITEM_UOM,
OT_PO_HEAD,
OT_PO_ITEM,
OS_LOCN_CURR_STK
WHERE (ITEM_UOM_CODE = IU_UOM_CODE AND ITEM_CODE = IU_ITEM_CODE)
AND ITEM_CODE = LCS_ITEM_CODE
AND ITEM_CODE = PI_ITEM_CODE
AND LCS_ITEM_CODE = PI_ITEM_CODE
AND LCS_LOCN_CODE ='RM'
AND PI_PH_SYS_ID = PH_SYS_ID
GROUP BY ITEM_CODE,ITEM_NAME,LCS_STK_QTY_BU,LCS_RCVD_QTY_BU,LCS_ISSD_QTY_BU,LCS_REJECT_QTY_BU,IU_MAX_LOOSE_1,ITEM_RORD_LVL,ITEM_RORD_QTY
ORDER BY ITEM_CODE ASC
YogeshAs you have no table aliases I can't tell what columns relate to which tables on your join conditions.
Can you not just put (+) next to the outer joined columns you require on the where clause? Or perhaps consider using ANSI syntax for the joins such as <tableA> LEFT OUTER JOIN <tableB> ON (<join conditions>) -
Outer Join Puzzle; Refactor Affects Results, Unexpectedly
Good afternoon. I have a complex query which is returning some unexpected results. Oddly, moving a specific join outside of the original query changes the results returned in a field from another table. This is a simplified version:
SELECT
A.PK,
A.Field1,
B.Field2,
C.Field3
FROM
A
INNER JOIN B ON A.PK = B.PK
LEFT JOIN C ON A.PK = C.PK
WHERE
A.Field = 'X'...running this query, I get 29 records but only one non-null value in C.Field3. If I then rewrite the query like this:
SELECT A.PK, A.Field1, B.Field2, A.Field3
FROM
SELECT
A.PK,
A.Field1,
C.Field3
FROM
A
LEFT JOIN C ON A.PK = C.PK
WHERE
A.Field = 'X'
) A
INNER JOIN B ON A.PK = B.PKSuddenly I get lots of values in Field3. I don't understand how this reorganization could affect the values returned. What am I missing?
The joins are all one-to-one, or to be exact one-to-zero-or-one.
Thank you,
JonathanHi, Jonathan,
I don't see any obvious mistakes.
I suspect that when you simplified the question, you inadvertently removed the part that was causing the problem.
Post a little sample data (CREATE TABLE and INSERT statements for all tables, relevant columns only) that produces the strange results.
I suggest not using aliases that are the same as the names of tables in the same query. For example, since a is a table name, also using a as an alias for the in-line view that joins a and c is just inviting confusion. It's probably not causing your present problem, but why not call the sub-query by some unique name, like ac? -
Same join query gives difeerent results on changing alias
I executed the following query,
select distinct(gr1.i_supergroups_names)
from dm_group_r gr1,
dm_group_r gr2
where gr1.r_object_id = gr2.r_object_id and
gr2.users_names = 'grass_mig3'
322 rows returned.
Immediately, I executed the same query again with a minor change in the join condition. Instead of GR2.USER_NAMES, i used GR1.USER_NAMES.
i.e.
select distinct(gr1.i_supergroups_names)
from dm_group_r gr1,
dm_group_r gr2
where gr1.r_object_id = gr2.r_object_id and
gr1.users_names = 'grass_mig3'
284 rows returned.
Would anyone be able to help me as to why the query is functioning like this?
This is the first time I am facing this problem Until now, I had never even thought that using different aliases could change the end result. Whenever I wrote a query, I would blindly use any one of the aliases?I'm just wondering if your queries are equivalent
select distinct(gr1.i_supergroups_names)
from dm_group_r gr1,
dm_group_r gr2
where gr1.r_object_id = gr2.r_object_id and
gr2.users_names = 'grass_mig3'
select distinct(gr1.i_supergroups_names)
from dm_group_r gr1,
dm_group_r gr2
where gr1.r_object_id = gr2.r_object_id and
gr1.users_names = 'grass_mig3' Well, I think they are.
Henry's question is valid why don't you just rewrite your query to
select distinct(gr1.i_supergroups_names)
from dm_group_r gr1
where gr1.users_names = 'grass_mig3'
and gr1.r_object_id is not null -- NULLs here got eliminated by the join aboveMessage was edited by:
Jens Petersen -
Outer Join not giving correct result
I have two tables=> tab_child_tmp (product_id,region,child_val,mst_product) and
tab_master_tmp (master_product_id,region,master_val)
tab_child_tmp.mst_product is the foreign key referencing tab_master_tmp.master_product_id.
Currently the tables are populated with below values
tab_child_tmp
PRODUCT_ID REGION CHILD_VAL MST_PRODUCT
Arm-01, CAL, 100, Arm-Master
Arm-01, DEL, 222, Arm-Master
Arm-01, CHEN, 55, Arm-Master
Arm-02, MUM, 69, Arm-Master
Arm-02, DEL, 90, Arm-Master
tab_master_tmp
MST_PRODUCT REGION MASTER_VAL
Arm-Master , CAL, 390
Arm-Master , DEL, 300
Arm-Master, CHEN, 450
Arm-Master, MUM, 600
Now I want to display the result in the below format
PRODUCT_ID REGION CHILD_VAL MASTER_VAL
1. Arm-01 , CAL, 100, 390
2. Arm-01 , DEL, 222, 300
3. Arm-01 , CHEN, 55, 450
4. Arm-01 , MUM, 0, 600
5. Arm-02 , MUM, 69, 600
6. Arm-02 , DEL, 90, 300
7. Arm-02 , CHEN, 0, 450
8. Arm-02 , CAL, 0, 390
When I am running the below query it is not returning the above 4,7 and 8 rows. Can you please provide the correct sql to get the above desired output
SELECT
a.product_id,
nvl(a.region,b.region) geo,
nvl(a.child_val,0)match_val,
b.master_val
FROM
tab_child_tmp a,
tab_master_tmp b
WHERE
a.mst_product(+) = b.master_product AND
a.region(+) = b.region
ThanksHi
Thanks for the reply. Please find below the details.
Oracle Version*
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for Solaris: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
Create Table Script_
create table TAB_CHILD_TMP
PRODUCT_ID VARCHAR2(50),
REGION VARCHAR2(100),
CHILD_VAL NUMBER,
MST_PRODUCT VARCHAR2(50)
create table TAB_MASTER_TMP
MST_PRODUCT VARCHAR2(50),
REGION VARCHAR2(100),
MASTER_VAL NUMBER
Insert Script_
INSERT INTO tab_child_tmp VALUES ('Arm-01','CAL',100,'Arm-Master');
INSERT INTO tab_child_tmp VALUES ('Arm-01','DEL',222,'Arm-Master');
INSERT INTO tab_child_tmp VALUES ('Arm-01','CHEN',55,'Arm-Master');
INSERT INTO tab_child_tmp VALUES ('Arm-Master','MUM',69,'PLC1');
INSERT INTO tab_child_tmp VALUES ('Arm-Master','DEL',90,'PLC1');
INSERT INTO tab_master_tmp VALUES ('Arm-Master','CAL',390);
INSERT INTO tab_master_tmp VALUES ('Arm-Master','DEL',300);
INSERT INTO tab_master_tmp VALUES ('Arm-Master','CHEN',450);
INSERT INTO tab_master_tmp VALUES ('Arm-Master','MUM',600);
INSERT INTO tab_master_tmp VALUES ('PLC1','MUM',199);
INSERT INTO tab_master_tmp VALUES ('PLC1','DEL',299);
INSERT INTO tab_master_tmp VALUES ('PLC1','CHEN',399);
Expected output logic*
Need to display the product value for each region along with the value of master product for the corresponding product and region. If a product doesn't belong to a particular region, but the corresponding master product is, then that value also needs to be displayed for that product and region with child value as zero.
ie. for product Arm-01 there is no record in tab_child_tmp for region "MUM", but it's master product 'Arm-Master' has a record for region 'MUM' in tab master_tmp table. So in ouput there will be a record for product 'Arm-01' and region-'MUM' with child value as 0 and master value as 600.
Expected Output*
PRODUCT_ID ~~~ REG ~~~ CHILD_VAL ~~~ MASTER_VAL
Arm-01 ~~~ CAL ~~~ 100 ~~~ 390
Arm-01 ~~~ DEL ~~~ 222 ~~~ 300
Arm-01 ~~~ CHEN ~~~ 55 ~~~ 450
Arm-01 ~~~ MUM ~~~ 0 ~~~ 600
Arm-MASTER ~~~ MUM ~~~ 69 ~~~ 199
Arm-MASTER ~~~ DEL ~~~ 90 ~~~ 299
Arm-MASTER ~~~ CHEN ~~~ 0 ~~~ 399
Please help -
Here is a query and desired output for a weekly sales report. The problem is that if no data exists for given businessdate, the report is empty. It should show store with zeroed totals.
NOTES:
1. storenbr must be string
2. bow, eow = beginning and end of week
3. I have no say-so on the date format
with report_stores as
( select 501 as storeid from dual union all
select 22 as storeid from dual union all
select 24 as storeid from dual
, store_details as
select 501 as storeid, '6504' as storenbr, 'Quincey Circle' as storename from dual union all
select 22 as storeid, '2385' as storenbr, 'Goodlet' as storename from dual union all
select 24 as storeid, '4290' as storenbr, 'Poplar' as storename from dual
, sales_data as
select 501 as storeid, to_date('12/01/2010', 'MM/DD/YYYY') as businessdate, 100 as sales_amt, 50 as guestcount from dual union all
select 22 as storeid, to_date('12/01/2010', 'MM/DD/YYYY') as businessdate, 200 as sales_amt, 50 as guestcount from dual union all
select 24 as storeid, to_date('12/01/2010', 'MM/DD/YYYY') as businessdate, 300 as sales_amt, 50 as guestcount from dual union all
select 501 as storeid, to_date('12/02/2010', 'MM/DD/YYYY') as businessdate, 400 as sales_amt, 100 as guestcount from dual union all
select 22 as storeid, to_date('12/02/2010', 'MM/DD/YYYY') as businessdate, 500 as sales_amt, 100 as guestcount from dual union all
select 24 as storeid, to_date('12/02/2010', 'MM/DD/YYYY') as businessdate, 600 as sales_amt, 100 as guestcount from dual
select storenbr
, to_date('01/30/2011', 'MM/DD/YYYY') as EOW
, sum(nvl(sales_amt, 0)) as sales_amount
, sum(nvl(sales.guestcount , 0)) as guestcount
from report_stores stores
inner join store_details details on details.storeid = stores.storeid
left outer join sales_data sales on sales.storeid = stores.storeid
and sales.businessdate between to_date('01/24/2011', 'MM/DD/YYYY') and to_date('01/30/2011', 'MM/DD/YYYY')
group by storename, to_date('01/30/2011', 'MM/DD/YYYY');However, when I make date dynamic by adding a dates table, I don't get output.
with report_dates as
select to_date('01/05/2011', 'MM/DD/YYYY') as businessdate, 'Wednesday' as day_name, 2 as week_nbr, to_date('01/03/2011', 'MM/DD/YYYY') as bow, to_date('01/09/2011', 'MM/DD/YYYY') as eow from dual union all
select to_date('01/24/2011', 'MM/DD/YYYY') as businessdate, 'Monday' as day_name, 5 as week_nbr, to_date('01/24/2011', 'MM/DD/YYYY') as bow, to_date('01/30/2011', 'MM/DD/YYYY') as eow from dual
, report_stores as
( select 501 as storeid from dual union all
select 22 as storeid from dual union all
select 24 as storeid from dual
, store_details as
select 501 as storeid, '6504' as storenbr, 'Quincey Circle' as storename from dual union all
select 22 as storeid, '2385' as storenbr, 'Goodlet' as storename from dual union all
select 24 as storeid, '4290' as storenbr, 'Poplar' as storename from dual
, sales_data as
select 501 as storeid, to_date('12/01/2010', 'MM/DD/YYYY') as businessdate, 100 as sales_amt, 50 as guestcount from dual union all
select 22 as storeid, to_date('12/01/2010', 'MM/DD/YYYY') as businessdate, 200 as sales_amt, 50 as guestcount from dual union all
select 24 as storeid, to_date('12/01/2010', 'MM/DD/YYYY') as businessdate, 300 as sales_amt, 50 as guestcount from dual union all
select 501 as storeid, to_date('12/02/2010', 'MM/DD/YYYY') as businessdate, 400 as sales_amt, 100 as guestcount from dual union all
select 22 as storeid, to_date('12/02/2010', 'MM/DD/YYYY') as businessdate, 500 as sales_amt, 100 as guestcount from dual union all
select 24 as storeid, to_date('12/02/2010', 'MM/DD/YYYY') as businessdate, 600 as sales_amt, 100 as guestcount from dual
select storenbr
, eow
, sum(nvl(sales_amt, 0)) as sales_amount
, sum(nvl(sales.guestcount , 0)) as guestcount
from report_stores stores
inner join store_details details on details.storeid = stores.storeid
right outer join sales_data sales on sales.storeid = stores.storeid
inner join report_dates dte on dte.businessdate = to_date('01/24/2010', 'MM/DD/YYYY')
-- and sales.businessdate between bow and eow
group by storenbr, eow
;What am I doing wrong? For kicks I also tried switching the JOINS like :
Select *
from sales_data sales
left outer join report_stores stores on stores.stoeid = sales.storeid but couldn't make this work either.Hi,
Thanks for posting the sample data in a useful form.
Don't forget to post the results you want to get from that data. Is this what you want?
STOR EOW SALES_AMOUNT GUESTCOUNT
6504 0 0
2385 0 0
4290 0 0If so, you want to inner-join sales_data and report_dates, and then outer-join that result set to report_stores.
Here's one way to do that:
SELECT details.storenbr
, dte.eow
, NVL (SUM (sales.sales_amt), 0) AS sales_amount
, NVL (SUM (sales.guestcount), 0) AS guestcount
FROM report_stores stores
INNER JOIN store_details details ON details.storeid = stores.storeid
LEFT OUTER JOIN ( sales_data sales
JOIN report_dates dte ON sales.businessdate BETWEEN dte.bow
AND dte.eow
) ON sales.storeid = stores.storeid
GROUP BY details.storenbr
, dte.eow
;As in your first query, you want the every row in report_stores to appear in the output, whether it matches anything in sales+dte or not, so you want to continue saying "FROM report_stores ... *LEFT* OUTER JOIN ...".
You'll notice that I changed
SUM (NVL (x, 0)) to
NVL (SUM (x), 0). Both give the same results, but, if you have 1000 rows, the former calls NVL 1000 times, but the latter only calls NVL once, so it's more efficient. -
I am a user of Dicoverer 4.1 and I write queries from the EUL. I need help in writing my query that will return all records in Table A and matching and Null values from Table B. A simple employee roster with all Names(Table A)and all addresses(Table B)including Null addresses. Here is the exact sql statement I get from a simple query that only gives me employees who have addresses (I know there are some who don't have addresses).
SELECT POSITION_EMPLOYEE_SECV.NAME_PERS, ADDRESS_SECV.LOCAL_ADDR_CITY
FROM CSUDB.POSITION_EMPLOYEE_SECV POSITION_EMPLOYEE_SECV, CSUDB.ADDRESS_SECV ADDRESS_SECV
WHERE ( ( POSITION_EMPLOYEE_SECV.SSAN_EMPL_CON_NR = ADDRESS_SECV.SSAN_EMPL_CON_NR ) );
How do I write the outer join that will give me all employees and include the ones with no address?
Thanks.Change the where clause to-
WHERE ((POSITION_EMPLOYEE_SECV.SSAN_EMPL_CON_NR = ADDRESS_SECV.SSAN_EMPL_CON_NR(+)));
Good luck! -
Outer join vs. 'SELECT in SELECT'
Hi All,
I am generally curious about which method to use between a Outer join and 'SELECT in SELECT'. We can have same result with both methods.
My question is, for real life complex queries, which method is more efficiant? less resource intensive? Any thories you guys have?
I am on Oracle 10.2 on lunix.
See my example below
-- First table
create table emp
id number,
name varchar2(1000),
constraint emp_pk primary key ( id )
-- second table. There will be 1 record, for few of the records in EMP table, in this table
create table leave
id number,
emp_id number,
leave_date date,
constraint leave_pk primary key (id),
constraint leave_fk foreign key ( emp_id ) references emp
create index leave_idx_1 on leave ( emp_id ) ;
-- Populate some sample data in there
insert into emp (id, name)
select object_id, object_name from dba_objects where rownum < 10001 ;
declare
cursor c1 is
select id from emp where mod(id,2) = 0 ;
v_id number := 1 ;
v_date DATE := '01-JAN-08';
begin
for c2 in c1
loop
insert into leave values ( v_id, c2.id, v_date );
v_id := v_id + 1;
v_date := v_date + 1;
end loop;
end;
-- Set autotrace
set autotrace traceonly explain
-- =================================
-- Outer join
-- =================================
select e.id, e.name, l.id, l.leave_date
from emp e, leave l
where e.id = l.emp_id (+) ;
-- ===================================
-- select in select to get same results as above outer join
-- ===================================
select e.id, e.name,
(select l.id from leave l where l.emp_id = e.id ) leave_id,
(select l.leave_date from leave l where l.emp_id = e.id ) leave_date
from emp e ;My hidden question, how these two methods internally work? in the plan we can only see something like 'hash join right outer' or something like that. But how exactly outer join is executed? how is the result formed?
I have got following plans for the two methods
SQL> select e.id, e.name, l.id, l.leave_date
2 from emp e, leave l
3 where e.id = l.emp_id (+) ;
Elapsed: 00:00:00.03
Execution Plan
Plan hash value: 98076489
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 10000 | 5371K| 16 (7)| 00:00:01 |
|* 1 | HASH JOIN RIGHT OUTER| | 10000 | 5371K| 16 (7)| 00:00:01 |
| 2 | TABLE ACCESS FULL | LEAVE | 5012 | 171K| 6 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL | EMP | 10000 | 5029K| 9 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - access("E"."ID"="L"."EMP_ID"(+))
Note
- dynamic sampling used for this statement
SQL> select e.id, e.name,
2 (select l.id from leave l where l.emp_id = e.id ) leave_id,
3 (select l.leave_date from leave l where l.emp_id = e.id ) leave_date
4 from emp e ;
Elapsed: 00:00:00.18
Execution Plan
Plan hash value: 2670217481
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 10000 | 5029K| 9 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| LEAVE | 50 | 1300 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | LEAVE_IDX_1 | 20 | | 1 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID| LEAVE | 50 | 1100 | 2 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | LEAVE_IDX_1 | 20 | | 1 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | EMP | 10000 | 5029K| 9 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - access("L"."EMP_ID"=:B1)
4 - access("L"."EMP_ID"=:B1)
Note
- dynamic sampling used for this statementPlease let me know your thoughts.
Thanks in advanceA better indicator of performance would be to look at the number of consistent gets that are required to execute the query.
In my environment:
SQL> SELECT * FROM V$VERSION;
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE 10.2.0.4.0 Production
TNS for 64-bit Windows: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production
SQL> SHOW PARAMETER OPT
NAME TYPE VALUE
filesystemio_options string
object_cache_optimal_size integer 102400
optimizer_dynamic_sampling integer 2
optimizer_features_enable string 10.2.0.4
optimizer_index_caching integer 0
optimizer_index_cost_adj integer 100
optimizer_mode string ALL_ROWS
optimizer_secure_view_merging boolean TRUE
plsql_optimize_level integer 2The OUTER JOIN produced the following results:
SQL> select e.id, e.name, l.id, l.leave_date
2 from emp e, leave l
3 where e.id = l.emp_id (+) ;
10000 rows selected.
Execution Plan
Plan hash value: 98076489
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 10000 | 380K| 9 (12)| 00:00:01 |
|* 1 | HASH JOIN RIGHT OUTER| | 10000 | 380K| 9 (12)| 00:00:01 |
| 2 | TABLE ACCESS FULL | LEAVE | 5017 | 80272 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL | EMP | 10000 | 224K| 5 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - access("E"."ID"="L"."EMP_ID"(+))
Statistics
0 recursive calls
0 db block gets
723 consistent gets
0 physical reads
0 redo size
364047 bytes sent via SQL*Net to client
7672 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processedThe inline subquery produced these results:
SQL> select e.id, e.name,
2 (select l.id from leave l where l.emp_id = e.id ) leave_id,
3 (select l.leave_date from leave l where l.emp_id = e.id ) leave_dat
4 from emp e ;
10000 rows selected.
Execution Plan
Plan hash value: 1706216391
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 10000 | 224K| 5 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| LEAVE | 1 | 9 | 3 (0)| 00:00:01 |
|* 2 | TABLE ACCESS FULL| LEAVE | 1 | 13 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| EMP | 10000 | 224K| 5 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - filter("L"."EMP_ID"=:B1)
2 - filter("L"."EMP_ID"=:B1)
Statistics
0 recursive calls
0 db block gets
360705 consistent gets
0 physical reads
0 redo size
364053 bytes sent via SQL*Net to client
7672 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processedSee the 723 consistent gets versus 360705? That is a huge difference.
The second method may be more viable if you create indexes on the columns in the leave table that you are joining to your EMP table.
For example:
SQL> CREATE INDEX LEAD_ID_IDX ON LEAVE(EMP_ID, ID, LEAVE_DATE);
Index created.
SQL> set autotrace traceonly
SQL> select e.id, e.name,
2 (select l.id from leave l where l.emp_id = e.id ) leave_id,
3 (select l.leave_date from leave l where l.emp_id = e.id ) leave_date
4 from emp e ;
10000 rows selected.
Execution Plan
Plan hash value: 1822800249
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 10000 | 224K| 5 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN | LEAD_ID_IDX | 1 | 9 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | LEAD_ID_IDX | 1 | 13 | 2 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| EMP | 10000 | 224K| 5 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - access("L"."EMP_ID"=:B1)
2 - access("L"."EMP_ID"=:B1)
Statistics
1 recursive calls
0 db block gets
22111 consistent gets
19 physical reads
0 redo size
364053 bytes sent via SQL*Net to client
7672 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processedThe query improved by a more than a factor of 10 with the index but the consistent gets are still significantly higher then the OUTER JOIN query. Additionally I always try and take the approach when developing queries to minimize the number of table accesses possible. In your second place you have to access the LEAVE table twice, instead of once in the first query. -
Choice of left or right outer join
Hi Experts,
I have a two tables like named as emp demo
desc emp
empname varchar2(50)
empid number
desc demo
empname varchar2(50)
empid number
when i implement the below quries i'm getting the same o/p.
queries like
select e.ename from emp e left outer join demo d on (e.empid=d.empid);
select e.ename from demo d right outer join emp e on (d.empid=e.empid);
In this case which query is most prefer
Thnks in advance
HHi,
943338 wrote:
Hi Experts,
I have a two tables like named as emp demo
desc emp
empname varchar2(50)
empid number
desc demo
empname varchar2(50)
empid number
when i implement the below quries i'm getting the same o/p.Right. You're getting the same error, because there is no ename column. If you change ename to empname, then you'll still get the same results, because
x LEFT OUTER JOIN y ON zis equivalent to
y RIGHT OUTER JOIN x ON zin results and performance.
queries like
select e.ename from emp e left outer join demo d on (e.empid=d.empid);
select e.ename from demo d right outer join emp e on (d.empid=e.empid);
In this case which query is most preferBoth are equally efficient.
Since most people never use RIGHT OUTER JOIN, it might make maintenance eaiser if you don't use it, either. I would use LEFT OUTER JOIN. -
One-to-many outer join in MView, is possible?
Re: 10g R2
Is it simply not possible to have fast refresh on outer joins that are 1-to-many relations? I have in this script a unique key addition to "fix" it, but it restricts something that I don't want restricted. If indeed this is how it should work, are there any strategies for improving performance for queries on this type of thing? The "fact_table" in this example is actually another materialized view with simple inner joins, so that works perfectly, but I was trying to improve query performance in this case too.
Run the script w/ dbms output...all self contained within the schema.
drop materialized view log on fact_Table;
drop materialized view log on outer_detail;
drop materialized view mview_test;
drop table outer_detail cascade constraints;
drop table fact_Table cascade constraints;
create table fact_table (myid number primary key, fact_attrib varchar2(10));
create table outer_detail (myid number primary key, outer_attrib varchar2(19), fact_table_id number, constraint fk_outer_to_Fact foreign key (fact_table_id) references fact_table(myid));
CREATE MATERIALIZED VIEW LOG ON fact_table WITH ROWID;
CREATE MATERIALIZED VIEW LOG ON outer_detail WITH ROWID;
declare
v_capabilities sys.ExplainMVArrayType ;
begin
dbms_mview.explain_mview('SELECT ft.rowid "ftrid", ' ||
'od.rowid "odrid", ' ||
'ft.myid fact_id, ' ||
'od.myid outer_id, ' ||
'ft.fact_attrib, ' ||
'od.outer_attrib ' ||
'FROM fact_table ft, outer_detail od ' ||
'WHERE ft.myid = od.fact_table_id (+)', v_capabilities);
dbms_output.put_line('ATTEMPT 1:');
dbms_output.put_line('==============================================');
for v_capability in (select capability_name, possible, related_text, msgtxt from table (v_capabilities))
loop
dbms_output.put_line('==============================================');
dbms_output.put_line('==============================================');
dbms_output.put_line(v_capability.capability_name);
dbms_output.put_line(v_capability.possible);
dbms_output.put_line(v_capability.related_text);
dbms_output.put_line(v_capability.msgtxt);
end loop;
end;
/*CREATE MATERIALIZED VIEW mview_test
PARALLEL BUILD IMMEDIATE
REFRESH FAST ON COMMIT WITH ROWID
AS
SELECT ft.rowid "ftrid",
od.rowid "odrid",
ft.myid fact_id,
od.myid outer_id,
ft.fact_attrib,
od.outer_attrib
FROM fact_table ft, outer_detail od
WHERE ft.myid = od.fact_table_id (+);
-- I'd like it to run without this constraint, is it not possible?
alter table outer_detail add constraint unk_outer_detail unique (fact_table_id);
declare
v_capabilities sys.ExplainMVArrayType ;
begin
dbms_mview.explain_mview('SELECT ft.rowid "ftrid", ' ||
'od.rowid "odrid", ' ||
'ft.myid fact_id, ' ||
'od.myid outer_id, ' ||
'ft.fact_attrib, ' ||
'od.outer_attrib ' ||
'FROM fact_table ft, outer_detail od ' ||
'WHERE ft.myid = od.fact_table_id (+)', v_capabilities);
dbms_output.put_line('');
dbms_output.put_line('');
dbms_output.put_line('');
dbms_output.put_line('ATTEMPT 2:');
dbms_output.put_line('==============================================');
for v_capability in (select capability_name, possible, related_text, msgtxt from table (v_capabilities))
loop
dbms_output.put_line('==============================================');
dbms_output.put_line('==============================================');
dbms_output.put_line(v_capability.capability_name);
dbms_output.put_line(v_capability.possible);
dbms_output.put_line(v_capability.related_text);
dbms_output.put_line(v_capability.msgtxt);
end loop;
end;
/Edited by: ORA-01435 on Sep 30, 2009 12:54 PMThat's what I thought too. As far as I'm concerned, this is perfectly acceptable. Of course I'm in 10g R2, but:
http://download.oracle.com/docs/cd/B19306_01/server.102/b14223/basicmv.htm#sthref534
I keep re-reading the rules, trying to see why it thinks I'm violating one of them. Might have to meta-link this one.
Just ran this on a different box, ran fine. Seem to have configuration issues between the boxes.
Edit: Just determined that the boxes that this doesn't work on have Oracle parameters for compatibility set to 10.1.0.2.0, I'll change them and check if it modifies behavior
Edited by: ORA-01435 on Oct 1, 2009 7:44 AM -
OJ syntax for multi-table left outer join with MS Oracle Driver
I have a multi-table left outer join that works fine in SQL Server ODBC Driver, Oracle ODBC driver 8.01.07.00, but not with Microsoft ODBC Driver for Oracle 2.573.7326.0
SELECT * from { oj A LEFT OUTER JOIN B ON A.col1 = B.col1 LEFT OUTER JOIN C ON A.col1 = C.col1 }
I noticed someone had a similar problem (the proposed solution doesn't work):
http://www.justpbinfo.com/listarchive/msg02874.html
Does anyone know how to get this working with the Microsoft ODBC Driver for Oracle? Or does it just not work?The Microsoft ODBC Driver for Oracle 2.573.7326.0 does perform the same 'fix up' with {oj} in Oracle 8i. The problem is that it doesn't work when joining more than two tables:
This works:
SELECT * from { oj A LEFT OUTER JOIN B ON A.col1 = B.col1}
This doesn't work:
SELECT * from { oj A LEFT OUTER JOIN B ON A.col1 = B.col1 LEFT OUTER JOIN C ON B.col1 = C.col1 }
(The second query will work with the Oracle Oracle ODBC driver, with a bit of tweaking. But I haven't found a way to get it to work with the Microsoft ODBC Driver for Oracle 2.573.7326.0. My suspicion is that it just doesn't work.)
Gavin -
Hi,
I have two Oracle tables in the physical layer: a fact table and a dimension table.
The fact table (FACT_TBL) like this:
CURR_MTH | PREV_MTH | CURR_GRADE | PREV_GRADE | CITY | VALUE
Jun | May | B | A | X | 5
Jun | May | A | A | Y | 10
Jun | May | C | C | X | 15
Jun | May | D | C | Y | 20
And the dimension table (GRADE_TBL) like this:
GRADE | GRADE_NAME
A | A
B | B
C | C
D | D
I joined those two tables above in the physical layer using GRADE field. Then, I created a business model using those two tables. I want to create a 4x4 matrix report with PREV_GRADE as the first column and the CURR_GRADE accross to the right like this:
CURR_MONTH PROMPT = Jun
PREV_MONTH PROMPT = May
CITY PROMPT = X
PREV_GRADE | A | B | C | D |
A | (null) | 5 | (null) | (null) |
B | (null) | (null) | (null) | (null) |
C | (null) | (null) | 15 | (null) |
D | (null) | (null) | (null) | (null)|
The problem is that I couldn't show all grade (A to D) in the PREV_GRADE column in that table. Every time I filter the CITY in the prompt to X, I always get only A and C. The B and D rows are suppressed. How do I achieve the left outer join that I wanted above? Thanks a lot for the help.hi,
this can be done in BMM layer.
select the required BMM model. Right click and select "Buisness Model Diagram" and "whole diagram" .
now double click on the joining link and specify the type of join here. (assuming you have used "New Complex join" to join these tables). -
I have records in a table:
TASKS
=====
TASKID TASKCD
1000 AD
1001 AD
1002 AD
1010 EO
1011 EO
1012 EO
1013 EO
EOs tasks depends on AD tasks and we have this dependency relationship in other table:
DEPTASKS
TASKID DEPID DEPCD
1010 1000 COMPLIES
1011 1001 COMPLIES
I need to display those AD tasks that does not have any record in DEPTASKS i.e taskid = 1002 as well
as those that has record in DEPTASKS.I am able to get the those ADs using outer join that does not have entry in
DEPTASKS i.e
(select taskad.taskid adid, taskad.taskcd,taskeo.taskid eoid,taskeo.task_cd
from tasks adtask,
tasks eotask) adeo, deptasks
where
adeo.eoid = deptasks.taskid(+)
and deptasks.dep-task-id(+) = adid
Problem: I also have to use one more filter i.e
where DEPCD = 'COMPLIES'
I.E :
adeo.eoid = deptasks.taskid(+)
and deptasks.dep-task-id(+) = adid
and DEPCD = 'COMPLIES'
when I use this filter, it again filters those ADs which does not have records in DEPTASKS.
Any suggestion how to control this scenerio.Any suggestion how to control this scenerio.Here's a suggestion to "control" this scenario.
SQL> @test3
SQL> --
SQL> with tasks as (
2 select 1000 as taskid, 'AD' as taskcd from dual union all
3 select 1001, 'AD' from dual union all
4 select 1002, 'AD' from dual union all
5 select 1010, 'EO' from dual union all
6 select 1011, 'EO' from dual union all
7 select 1012, 'EO' from dual union all
8 select 1013, 'EO' from dual),
9 deptasks as (
10 select 1010 as taskid, 1000 as depid, 'COMPLIES' as depcd from dual union all
11 select 1011, 1001, 'COMPLIES' from dual union all
12 select 1013, 1002, 'DOESNOTCOMPLY' from dual)
13 --
14 select t.taskid as t_taskid, t.taskcd as t_taskcd,
15 d.taskid as d_taskid, d.depid as d_depid, d.depcd as d_depcd
16 from tasks t, deptasks d
17 where t.taskid = d.taskid(+)
18 and d.depcd(+) = 'COMPLIES';
T_TASKID T_TASKCD D_TASKID D_DEPID D_DEPCD
1010 EO 1010 1000 COMPLIES
1011 EO 1011 1001 COMPLIES
1001 AD
1002 AD
1013 EO
1000 AD
1012 EO
7 rows selected.
SQL>
SQL>HTH
isotope -
SQL7 to ORA9i problem w/ outer joins
The information provided for the new release 9.2.0.1.7 of the Migration workbench explained that outer joins would be easier to convert with the added parse options. I have several stored procedures with outer joins that are still giving warning errors with the latest version. I have selected the parse options to generate Oracle 8i outer joins and have also left it unchecked. I continue to get the same errors for the outer joins. Here is an example of the join:
(SELECT DISTINCT Product_tblProductRegion.ProductRegion_ID
FROM Product_tblProductRegion LEFT JOIN Product_tblMaster ON Product_tblProductRegion.ProductRegion_ProductID = Product_tblMaster.Product_ID
WHERE Product_tblMaster.Product_ID Is Null)
Please let me know what information is needed to work through this problems.
Thank you.Logged bug, Bug No: 3393782
The workaround is to manually copy the ANSI Outer join from the TSQL to PLSQL. There appears to be a conflict between two fixes in the code, the ANSI join fix and the table function code, which is applicable to sqlserver 2k.
Turloch
Maybe you are looking for
-
What di I need on a Mac Mini to import Pages documents from an iPad-mini
What do I need on my MacMini to import Pages documents from an iPad-mini?
-
Does anybody know a similar case size to the n580...ordered one for my daughter for christmas and I'm hoping to get her a skin as well...but skin-it does not have the n580 listed as one of the options. It is very close to my g570, but not exact.
-
Can no longer access home movies from imovie theater on atv. Keep seeing the circle while waiting.
-
Hello, I ehanced an existing BPM where a send step sends data to a J2EE system. I inserted a switch and put the existing send step to one branche and a new send step to the otherweise-branche. The new send step interrupt with an error: <b>No exceptio
-
Can I edit a Clip Notes PDF?
Hello, I'm using Adobe Premiere Pro CS3 to export QuickTime files to PDF. Since the URL is entered with the Clip Notes dialog, is there a way to change this URL in the PDF after it has been created? I do have Acrobat Professional. I did figure out th