Issue of OUTER JOIN
So, for the following data:CREATE TABLE MOVIE
(TK NUMBER(10,0) primary key,
TITLE VARCHAR2(40),
CODE_GENRE VARCHAR2(2));
/
CREATE TABLE ACTOR
(TK NUMBER(10,0) primary key,
NAME VARCHAR2(40));
/
CREATE TABLE MOVIE_ACTOR_XREF
(TK_MOVIE NUMBER(10,0) references movie (tk),
TK_ACTOR NUMBER(10,0) references actor (tk));
/
INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (1,'MAN ON FIRE','D');
INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (2,'THE MATRIX','SF');
INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (3,'PEE WEE''S BIG ADVENTURE','C');
INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (4,'NACHO LIBRE','C');
INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (5,'UP','CH');
INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (6,'HELLRAISER','H');
INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (7,'BILL AND TED''S EXCELLENT ADVENTURE','C');
INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (8,'MEMENTO','M');
INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (9,'GHOST BUSTERS','C');
INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (10,'MUMFORD','C');
INSERT INTO ACTOR (TK,NAME) VALUES (1,'DENZEL WASHINGTON');
INSERT INTO ACTOR (TK,NAME) VALUES (2,'DAKOTA FANNING');
INSERT INTO ACTOR (TK,NAME) VALUES (3,'KEANU REAVES');
INSERT INTO ACTOR (TK,NAME) VALUES (4,'PEE WEE HERMAN');
INSERT INTO ACTOR (TK,NAME) VALUES (5,'JACK BLACK');
INSERT INTO ACTOR (TK,NAME) VALUES (6,'ED ASNER');
INSERT INTO ACTOR (TK,NAME) VALUES (7,'PINHEAD');
INSERT INTO ACTOR (TK,NAME) VALUES (8,'GUY PIERCE');
INSERT INTO ACTOR (TK,NAME) VALUES (9,'BILL MURRAY');
INSERT INTO ACTOR (TK,NAME) VALUES (10,'DAN AKROYD');
INSERT INTO ACTOR (TK,NAME) VALUES (11,'JASON LEE');
INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (1,1);
INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (1,2);
INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (2,3);
INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (3,4);
INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (4,5);
INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (5,6);
INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (6,7);
INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (7,3);
INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (8,8);
INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (9,9);
INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (9,10);
INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (10,11);
Why the following 2 queries do not produce the same results? The FILM table is the table of LEFTermost in outer joins, so I thought I could place criteria against it in the FROM clause and ending up with the same result:select m.title, m.code_genre, a.name
from movie m
left outer
join movie_actor_xref x on (m.tk = x.tk_movie
and m.code_genre = 'C')
left outer
join actor a on (x.tk_actor = a.tk);
select m.title, m.code_genre, a.name
from movie m
left outer
join movie_actor_xref x on (m.tk = x.tk_movie)
left outer
join actor a on (x.tk_actor = a.tk)
where m.code_genre = 'C';
Thank you-= Chuck
Hi, Chuck,
chuckers wrote:
So, for the following data:CREATE TABLE MOVIE (TK NUMBER(10,0) primary key, TITLE VARCHAR2(40), CODE_GENRE VARCHAR2(2)); / CREATE TABLE ACTOR (TK NUMBER(10,0) primary key, NAME VARCHAR2(40)); / CREATE TABLE MOVIE_ACTOR_XREF (TK_MOVIE NUMBER(10,0) references movie (tk), TK_ACTOR NUMBER(10,0) references actor (tk)); / INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (1,'MAN ON FIRE','D'); INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (2,'THE MATRIX','SF'); INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (3,'PEE WEE''S BIG ADVENTURE','C'); INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (4,'NACHO LIBRE','C'); INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (5,'UP','CH'); INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (6,'HELLRAISER','H'); INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (7,'BILL AND TED''S EXCELLENT ADVENTURE','C'); INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (8,'MEMENTO','M'); INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (9,'GHOST BUSTERS','C'); INSERT INTO MOVIE (TK,TITLE,CODE_GENRE) VALUES (10,'MUMFORD','C'); INSERT INTO ACTOR (TK,NAME) VALUES (1,'DENZEL WASHINGTON'); INSERT INTO ACTOR (TK,NAME) VALUES (2,'DAKOTA FANNING'); INSERT INTO ACTOR (TK,NAME) VALUES (3,'KEANU REAVES'); INSERT INTO ACTOR (TK,NAME) VALUES (4,'PEE WEE HERMAN'); INSERT INTO ACTOR (TK,NAME) VALUES (5,'JACK BLACK'); INSERT INTO ACTOR (TK,NAME) VALUES (6,'ED ASNER'); INSERT INTO ACTOR (TK,NAME) VALUES (7,'PINHEAD'); INSERT INTO ACTOR (TK,NAME) VALUES (8,'GUY PIERCE'); INSERT INTO ACTOR (TK,NAME) VALUES (9,'BILL MURRAY'); INSERT INTO ACTOR (TK,NAME) VALUES (10,'DAN AKROYD'); INSERT INTO ACTOR (TK,NAME) VALUES (11,'JASON LEE'); INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (1,1); INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (1,2); INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (2,3); INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (3,4); INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (4,5); INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (5,6); INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (6,7); INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (7,3); INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (8,8); INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (9,9); INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (9,10); INSERT INTO MOVIE_ACTOR_XREF (TK_MOVIE,TK_ACTOR) VALUES (10,11);
Thanks for posting the CREATE TABLE and INSERT! It is very useful.
Why the following 2 queries do not produce the same results? The FILM table is the table of LEFTermost in outer joins, so I thought I could place criteria against it in the FROM clause and ending up with the same result:
We will call this first request 'Query 1.
select m.title, m.code_genre, a.name from movie m left outer join movie_actor_xref x on (m.tk = x.tk_movie and m.code_genre = 'C') left outer join actor a on (x.tk_actor = a.tk);
Left outer joins ensure that each row of the table to move will appear in the output.
If movie.code_genre = 'C', then he might have a match in movie_actor_xref.
If movie.code_genre! = 'C' (or NULL) then it will not be considered to match any line in movie_actor_xref, but since it is an outer join, that the rank of the film appears in the result set.
Let's call the other "Application 2" quuery
select m.title, m.code_genre, a.name from movie m left outer join movie_actor_xref x on (m.tk = x.tk_movie) left outer join actor a on (x.tk_actor = a.tk) where m.code_genre = 'C';
When all the joins are finsihed, all lines of film will be in the result set, if it corresponds to what in the other tables.
Unlike the query 1, 2 the query has a WHERE clause. You can think of the WHERE clause as being applied after all the joins are completed. The WHERE clause in the query 2 will remove all the lines where movie.code_genre! = 'C' (or NULL), so the final results will not include necessarily all movie lines.
Let's look at a specific example.
This line appears in the output of query 1:
TITLE CO NAME
-------------------- -- --------------------
UP CH
but there is no line of corresoponding in query output 2. Why not? What is the difference between Query1 and Query2? The difference is the condition of wheher "where m.code_genre = 'C'" applies to one of the outer joins (as in the query 1) or the game (as in query 2) set of results.
Try to run this query, I'll call the query 0 because it contains less query 1 or 2 of the query:
select m.title, m.code_genre, a.name
from movie m
left outer
join movie_actor_xref x on (m.tk = x.tk_movie)
left outer
join actor a on (x.tk_actor = a.tk)
;
Note that the query 0 does not speak code_genrel; It contains only the code that is used by query 1 and query 2. 0 query output includes this line:
TITLE CO NAME
-------------------- -- --------------------
UP CH ED ASNER
Query 1 produces a line of title = 'UP' but that line had a NULL value in the name column. This is because the query 1 was a condition of additional join between the film and actor_movie_xref. In query 1, lines of these two tables were regarded as a match only if movie.cide_genre =' it. The line with title = 'UP' a 'CH' code_genre, so it is not considered a match with actor_movie_xref. Since it is an outer join, however, the line stays in the result set, but the columns that would be provided by actor_move_xref are all NULL. 1 query is an outer join to the table of the actor. "Join condition"x.tk_actor = a.tk"fails, because x.tk_actor is null (all x columns have NULL value) on the title line =" upward ", but, again, since it is an outer join, this line is in the result set.
The difference between the 0 and 2 of the query request is 2 query has a WHERE clause. When the query 2 finishes to make all joins, but before she applies the WHERE clause, its result set is identical to the query result 0 set, including a line with title = 'UP '. Then the WHERE clause is applied, and any line that doesn't have a 'C' for his code_genre is eliminated.
Published by: Frank Kulash, October 13, 2011 15:44
Added example 'UP '.
Tags: Database
Similar Questions
-
Hi guys,.
I use Oracle 10 G database. When I run the query below, I am of course a mistake given that an outer join more then one table:
---------------------
---------------------SELECT MV_VAA_INC_MONTHLY_SUMMARY.Month_ID, MV_VAA_INC_MONTHLY_SUMMARY.PRIORITY, sum(MV_VAA_INC_MONTHLY_SUMMARY.CLOSED), decode(MV_VAA_INC_MONTHLY_SUMMARY.SLA_MET, 1, 0, 1), MV_VAA_INC_MONTHLY_SUMMARY.INCIDENT_NUMBER, to_char(MV_VAA_INC_MONTHLY_SUMMARY.FIRST_DAY_OF_THE_MONTH, 'Mon')||' '||to_char(MV_VAA_INC_MONTHLY_SUMMARY.FIRST_DAY_OF_THE_MONTH, 'yy'), INC_BREACH_SLA_DETAILS.RESPONSIBILITY FROM MV_VAA_INC_MONTHLY_SUMMARY , HPD_HELP_DESK, INC_BREACH_SLA_DETAILS, MIS_QUEUES_RESP INC_MIS_QUEUES_RESP WHERE ( ( INC_MIS_QUEUES_RESP.RESP = ANY ('TCS', 'NONTCS') ) AND ( ( MV_VAA_INC_MONTHLY_SUMMARY.FIRST_DAY_OF_THE_MONTH ) BETWEEN ( add_months(trunc(sysdate,'MM'), -4) ) AND ( trunc(sysdate,'MM') -1 ) ) AND MV_VAA_INC_MONTHLY_SUMMARY.Month_ID = 201110 AND MV_VAA_INC_MONTHLY_SUMMARY.INCIDENT_NUMBER (+) = HPD_HELP_DESK.INCIDENT_NUMBER AND INC_BREACH_SLA_DETAILS.INCIDENT_NUMBER=HPD_HELP_DESK.INCIDENT_NUMBER (+) AND INC_MIS_QUEUES_RESP.SUPPORT_GROUP_ID=HPD_HELP_DESK.ASSIGNED_GROUP_ID (+) ) GROUP BY MV_VAA_INC_MONTHLY_SUMMARY.Month_ID, MV_VAA_INC_MONTHLY_SUMMARY.PRIORITY, decode(MV_VAA_INC_MONTHLY_SUMMARY.SLA_MET, 1, 0, 1), MV_VAA_INC_MONTHLY_SUMMARY.INCIDENT_NUMBER, to_char(MV_VAA_INC_MONTHLY_SUMMARY.FIRST_DAY_OF_THE_MONTH, 'Mon')||' '||to_char(MV_VAA_INC_MONTHLY_SUMMARY.FIRST_DAY_OF_THE_MONTH, 'yy'), INC_BREACH_SLA_DETAILS.RESPONSIBILITY HAVING sum(MV_VAA_INC_MONTHLY_SUMMARY.CLOSED) = 1
But when I run the sub query quite similar, I do not receive an error.
-------------------------
-------------------------SELECT MV_VAA_INC_MONTHLY_SUMMARY.Month_ID, MV_VAA_INC_MONTHLY_SUMMARY.PRIORITY, sum(MV_VAA_INC_MONTHLY_SUMMARY.CLOSED), decode(MV_VAA_INC_MONTHLY_SUMMARY.SLA_MET, 1, 0, 1), MV_VAA_INC_MONTHLY_SUMMARY.INCIDENT_NUMBER, to_char(MV_VAA_INC_MONTHLY_SUMMARY.FIRST_DAY_OF_THE_MONTH, 'Mon')||' '||to_char(MV_VAA_INC_MONTHLY_SUMMARY.FIRST_DAY_OF_THE_MONTH, 'yy'), INC_BREACH_SLA_DETAILS.RESPONSIBILITY FROM MV_VAA_INC_MONTHLY_SUMMARY RIGHT OUTER JOIN HPD_HELP_DESK ON (MV_VAA_INC_MONTHLY_SUMMARY.INCIDENT_NUMBER=HPD_HELP_DESK.INCIDENT_NUMBER) LEFT OUTER JOIN INC_BREACH_SLA_DETAILS ON (INC_BREACH_SLA_DETAILS.INCIDENT_NUMBER=HPD_HELP_DESK.INCIDENT_NUMBER) LEFT OUTER JOIN MIS_QUEUES_RESP INC_MIS_QUEUES_RESP ON (INC_MIS_QUEUES_RESP.SUPPORT_GROUP_ID=HPD_HELP_DESK.ASSIGNED_GROUP_ID) WHERE ( ( INC_MIS_QUEUES_RESP.RESP = ANY ('TCS', 'NONTCS') ) AND ( ( MV_VAA_INC_MONTHLY_SUMMARY.FIRST_DAY_OF_THE_MONTH ) BETWEEN ( add_months(trunc(sysdate,'MM'), -4) ) AND ( trunc(sysdate,'MM') -1 ) ) AND INC_BREACH_SLA_DETAILS.RESPONSIBILITY NOT IN ( 'NONE' ) AND MV_VAA_INC_MONTHLY_SUMMARY.Month_ID = 201110 ) GROUP BY MV_VAA_INC_MONTHLY_SUMMARY.Month_ID, MV_VAA_INC_MONTHLY_SUMMARY.PRIORITY, decode(MV_VAA_INC_MONTHLY_SUMMARY.SLA_MET, 1, 0, 1), MV_VAA_INC_MONTHLY_SUMMARY.INCIDENT_NUMBER, to_char(MV_VAA_INC_MONTHLY_SUMMARY.FIRST_DAY_OF_THE_MONTH, 'Mon')||' '||to_char(MV_VAA_INC_MONTHLY_SUMMARY.FIRST_DAY_OF_THE_MONTH, 'yy'), INC_BREACH_SLA_DETAILS.RESPONSIBILITY HAVING sum(MV_VAA_INC_MONTHLY_SUMMARY.CLOSED) = 1
Please can you advise the reason.
See you soon,.
Khadi
Published by: BluShadow on November 11, 2011 10:54
addition of {noformat}{noformat} tags. Please read {message:id=9360002} and learn to do this yourself.
Hi, yaya,
888121 wrote:
Hi guys,.In fact I'm not guru in Oracle as such. The first query, I pasted works well.
You mean the second query (one with ANSI joins) is running fine and the first query (with signs +) is a mistake, right?
Looking at this request I created the joins in the second, but then I get this error. I just want to understand what is the difference in the ANSI query and mine is throwing this error.
Join ANSI rating supports outer joins to more than one table; the old syntax doesn't work. That's all there is to it. The ANSI syntax also supports FULL OUTER JOIN, and the old syntax does not work. There is nothing wrong with more than one table outer join, just as there is nothing wrong with a full outer join. You can do it with the old syntax, but just more coding.
Published by: Frank Kulash, November 11, 2011 08:16
-
Bad result in a left outer join in 12.1.0.2
Hallo,
We discovered a strange behaviour in a query. The query provides values in a column of outer join where there is no corresponding value in the table is attached to the outside.
When you expand this request by the "ORDER BY" then this query gives the correct result.
Example:
SQL > desc tb_a
Name Null? Typ
-------------------------------------------- ----------------------------
ID NOT NULL NUMBER (19)SQL > desc tb_b
Name Null? Typ
-------------------------------------------- ----------------------------
CLOSED NOT NULL NUMBER (1)
ID NOT NULL NUMBER (19)CCS_APPLICATION@icw01> select * from tb_a where id in (4148,4141,4195);
ID
----------
4148
4141
4195CCS_APPLICATION@icw01> select * from tb_b where id in (4148,4141,4195);
INTERNAL ID
---------- ----------
4148 0CCS_APPLICATION@icw01> SELECT
2 b.id AS b_id,
3 a.id AS a_id,
4 b.closed AS b_closed
5
6 tb_a a
7 LEFT OUTER JOIN tb_b b ON a.id = b.id
8 WHERE a.id IN (4148, 4195, 4141)
9 ORDER BY ASC a.id
10;B_ID ALLOCATION A_ID B_CLOSED
---------- ---------- ----------
4141
4148 4148 0
4195CCS_APPLICATION@icw01> SELECT
2 b.id AS b_id,
3 a.id AS a_id,
4 b.closed AS b_closed
5
6 tb_a a
7 LEFT OUTER JOIN tb_b b ON a.id = b.id
8 WHERE a.id IN (4148, 4195, 4141)
9 - ORDER BY ASC a.id
10;B_ID ALLOCATION A_ID B_CLOSED
---------- ---------- ----------
4148 4148 0
4141 4141
4195 4195instance parameter:
VALUE OF TYPE NAME
------------------------------------ ----------- ------------------------------
compatible string 12.1.0.2.0
optimizer_features_enable string 12.1.0.2
After ""alter system set optimizer_features_enable = ' 11.2.0.4 ';" the query provides the correct result in both cases (ordered and unordered).
Now the final question: is this a bug?
1480970 wrote:
Hallo! Yes, I searched the Support of Oracle. I found some similar entries, but not an exact match. To fix some issues
with 12.1.0.2.
There is another interesting clue when look you on the execution plan:
Note
-----
-the dynamic statistics used: dynamic sampling (level = 2)
- This is an adaptation plan
We have disabled (= FALSE) optimizer_adaptive_features and the query provides the correct values.
This could be a solution for us.
Looks like a pretty tight match for bug 18430870, even if it affects the two 12.1.0.1 and 12.1.0.2, which contradicts the Martin trial against 12.1.0.1.
The description of the bug mentions disabling "_projection_pushdown" (set to false) should also be a viable solution, perhaps if you want to give that a try and see if it is a different bug or not.
There are also a number of one-time fixes already available for download, maybe your version / platform is already covered, if the bug applies.
Randolf
-
Create a view which limits a large table, but also allows an outer join?
Oracle 10.2.0.4
CREATE TABLE MY_PAY_ITEMS
(EMP VARCHAR2 (8) NOT NULL)
, PAY_PRD VARCHAR2 (8) NOT NULL
, KEY1 VARCHAR2 (8) NOT NULL
, KEY2 VARCHAR2 (8) NOT NULL
, LN_ITEM VARCHAR2 (4) NOT NULL
, ITEM_AMT NUMBER (24.2) NOT NULL
VARCHAR2 (100) FILL NON-NULL)
INSERT INTO MY_PAY_ITEMS
SELECT A.EMP
B.PAY_PRD
C.KEY1
D.KEY2
E.LN_ITEM
F.ITEM_AMT
, ' '
FROM (SELECT TO_CHAR (ROWNUM, ' 00000000') 'EMP' FROM DUAL CONNECT BY LEVEL < = 50) has
, (SELECT '2010-' |) To_char(rowNum,'00') 'PAY_PRD' FROM DUAL CONNECT BY LEVEL < = 52) B
, (SELECT TO_CHAR (ROWNUM, ' 000') 'KEY1' FROM DUAL CONNECT BY LEVEL < = 8) C
, (SELECT TO_CHAR (ROWNUM, ' 000') 'Key2' FROM DUAL CONNECT BY LEVEL < = 5) D
, (SELECT TO_CHAR(ROWNUM,'000') 'LN_ITEM' FROM DUAL CONNECT BY LEVEL < = 20) E
(round (DBMS_RANDOM. VALUE * 400.2) "ITEM_AMT" of the double) F
CREATE A UNIQUE INDEX MY_PAY_ITEMS ON MY_PAY_ITEMS (MEP, PAY_PRD, KEY1, KEY2, LN_ITEM)
CREATE TABLE MY_ITEM_DISPLAY
(THE VARCHAR2 (4) OF DISPLAY_CODE NOT NULL)
, NUMBER (2) SEQUENCE NON-NULL
, COLUMN_ITEM1 VARCHAR2 (4) not null
, COLUMN_ITEM2 VARCHAR2 (4) not null
, COLUMN_ITEM3 VARCHAR2 (4) not null
COLUMN_ITEM4 VARCHAR2 (4) not null)
INSERT INTO MY_ITEM_DISPLAY VALUES ('01 ', 10, '001', '003', '004',' 005');
INSERT INTO MY_ITEM_DISPLAY VALUES ('01 ', 20 '007', '013', '004',' 009');
INSERT INTO MY_ITEM_DISPLAY VALUES ('01', 30 ' 001', '004', '009',' 011');
INSERT INTO MY_ITEM_DISPLAY VALUES ('01', 40, '801 ', ' 304 ', 209',' 111');
INSERT INTO MY_ITEM_DISPLAY VALUES ('02 ', 10, '001', '003', '004',' 005');
INSERT INTO MY_ITEM_DISPLAY VALUES ('02 ', 20 '007', '013', '004',' 009');
INSERT INTO MY_ITEM_DISPLAY VALUES ('02', 30 ' 001', '004', '009',' 011');
MY_PAY_ITEMS is a table that stores line of payslip items. It has a total area of 500,000,000 lines.
PEM is the unique id, we have about 200,000 employees (with about 50,000 being active today).
PAY_PRD is a weekly pointer (2010-01, 2010-02, 2010-52), we have the 2004 data and add a new pay period each week. 2010 01 is defined as the first Monday in 2010 for the first Sunday in 2010, etc.
Key1 is an internal key, it follows the chronology in the pay period.
KEY2 is a child of KEY1, there follows the sequence of events in KEY1.
LN_ITEM is the component of actual compensation resulting from the event, on average, a person produces 20 lines per event. Note that in this example, everyone gets the same LN_ITEM values, but in practice it is selected 20 of 300
ITEM_AMT is the net salary per command line.
FILLING is a set of fields that are unrelated to this issue, but act as a brake on the charges of the line.
MY_ITEM_DISPLAY is an array that describes how some screens should display items. The screen itself is a grid of 4 poles, with the content of each cell is defined as a LN_ITEMS search to retrieve the relevant LN_AMT.
We have an application that receives a DISPLAY_CODE and an EMP. It automatically creates an sql statement in the sense of
SELECT * FROM MY_VIEW WHERE DISPLAY_CODE =: 1 AND EMP =: 2
and returns the output to the user.
My challenge is that I need to rewrite MY_VIEW as follows:
(1) (select the relevant lines from MY_ITEM_DISPLAY where DISPLAY_CODE =: 1)
(2) select the relevant all MY_PAY_ITEMS lines that meet the criteria
(a) EMP =: 2
(b) PAY_PRD = (a more recent for EMP and sysdate, so if he got last paid 2010-04, return 2010-04)
(c) KEY1 = (highest key1 in EMP and PAY_PRD)
(d) KEY2 = (highest key2 in KEY1, PAY_PRD and EMP)
(3) I then need to cross reference to create tabular output
(4) Finally, I have to return a 0 line where there is no LN_ITEMs (DISPLAY_CODE 01, 40 sequence contains possible values for this scenario)
The following query is part of it (but not the PAY_PRD, KEY1, KEy2)
Select * from)
SELECT A.DISPLAY_CODE
B.EMP
A.SEQUENCE
, MAX (DECODE (B.LN_ITEM, A.COLUMN_ITEM1, B.ITEM_AMT, 0)) 'COL1 '.
, MAX (DECODE (B.LN_ITEM, A.COLUMN_ITEM2, B.ITEM_AMT, 0)) 'COL2 '.
, MAX (DECODE (B.LN_ITEM, A.COLUMN_ITEM3, B.ITEM_AMT, 0)) 'COL3 '.
, MAX (DECODE (B.LN_ITEM, A.COLUMN_ITEM4, B.ITEM_AMT, 0)) 'COL4 '.
OF MY_ITEM_DISPLAY A, MY_PAY_ITEMS B
WHERE B.PAY_PRD = ' 2010-03'
GROUP OF A.DISPLAY_CODE, B.EMP, A.SEQUENCE)
WHERE DISPLAY_CODE = '01'
AND EMP = '0000011'
SEQUENCE ORDER
My questions
(1) how I do PAY_PRD, KEY1, KEY2 forced, can I use a form any of ROW_NUMBER() FUNCTION?
(2) how can I deal with the fact that none of the 4 LN_ITEMS column can exist (see sequence 40, none of these can exist)... Ideally the SQL above should return
01, 0000011, 10, < a digit - > < number > - < a digit - > < some number >
01, 0000011, 20, < a digit - > < number > - < a digit - > < some number >
01, 0000011, 30, < a number--> < number > - < number > - < number > -
01, 0000011, 40, 0, 0, 0, 0
I tried a UNION, but it prevented the view to eliminate most of the MY_PAY_ITEMS lines, because it solves ALL MY_PAY_ITEMS instead of simply retrieve lines for the EMP passed to the view. The same seems to be true for outer joins.
Hi Paula,
It does not handle SEQNUM 40, it's just that your second set of test data did not SEQNUM 40. When I put in the first set of values MY_ITEM_DISPLAY, I get:
DISP EMP SEQUENCE COL1 COL2 COL3 COL4
---- -------- ---------- ---------- ---------- ---------- ----------
01 00000011 10 101.1 103.1 105.1 104.1
01 00000011 20 107.1 113.1 104.1 109,1
01 00000011 30 101.1 104.1 109.1 99.99
01 00000011 40 0 0 0 0
If this isn't the issue, you will need to explain the requirement of "outer join" and what you want more. Apart from his return nothing if there is absolutely no element of remuneration of the employee, this query will always return a line for each line MY_ITEM_DISPLAY for the display_code. If there is absolutely no data, no return line seems reasonable.
-
outer join on the aggregate query
This is probably a relatively simple matter, as long as I explain it well enough:
I have two tables:
categorycodes and properties
categorycodes is a lookup table.
both tables have a catcode field which is a char (1) that contains matching data (only the numbers 1 to 6)
CREATE
TABLE CATEGORYCODES
(
CATCODE CHAR (1 BYTE) NOT NULL,
DESCRIPTION VARCHAR2 (25 BYTE) NOT NULL,
CONSTRAINT CATEGORYCODES_PK PRIMARY KEY (CATCODE) ALLOW
)
catCode
1
2
3
4
5
6
The properties table has approximately 600 000 records. The properties table also has a field named parcelno which is a tank (9). It contains a string of figures and numbers only.
What I would like is:
catCode, count (*)
1 580
2 300
3 3000
4 235
5 0
6 80
I limited the results of the query to make sure it was a game that would not all catcodes in it. I have trouble to get the one with zero to display. I know that this has to do with how I do the join, but I don't know what.
It is a sample of what I've tried:
Select i.
Of
(select catcode, count (*)
property p
where substr (parcelno, 1, 3) = ' 871 "
Catcode group) i
outer join right categorycodes cc
We i.catcode = cc.catcode;
I'm not worried about the situations where catcode is null in the properties. Parcelno cannot be null.
Hello
Looks like your query should work; except that you won't COUNT (*); That would make each issue at least 1. COUNT (*) means that count the total number of lines, no matter what is on them, so he'll see the line with just the catcode of the lookup table that matches nothing and which count as 1. You want to count the number of rows in the table of properties, so expect a column of the properties that cannot be NULL.
Here is a slightly different way
SELECT c.catcode
EARL of (p.catcode) AS cnt
OF categorycodes c
P ON p.catcode = c.catcode LEFT OUTER JOIN properties
AND SUBSTR (p.parcelno
1
3
) = ' 871 "
;
If the condition about 871' ' part of the join condition, then you don't need a subquery.
.
I hope that answers your question.
If not, post a small example data (CREATE TABLE and only relevant columns, INSERT statements) for all of the tables involved and also publish outcomes from these data.
Point where the above statement is erroneous results, and explain, using specific examples, how you get the right result of data provided in these places.Always say what version of Oracle you are using (for example, 11.2.0.2.0).
See the FAQ forum: https://forums.oracle.com/message/9362002
-
Hello world
I have a query that is not working properly. I'm trying to join two tables and I or condition and outer join
I get the error message
So, basically in the above query I say that if the type = "TKE" do not join on all columns of pos. If type is not TKE then do all the joints on all columns POS etc.ORA-01719: outer join operator (+) not allowed in operand of OR or IN my query is as follow SELECT l.* FROM table1 l, table2 map WHERE (NVL(l.id, '-99') = NVL(map.id(+), NVL(l.id, '-99')) AND l.TYPE = 'TKE') ) OR (NVL(l.id, '-99') = NVL(map.id(+), NVL(l.id, '-99')) AND NVL(l.type, '-99') = NVL(map.type(+), NVL(l.type, '-99')) AND NVL(l.pos_22, '-99') = NVL(map.pos_22(+),NVL(l.pos_22, '-99')) AND NVL(l.pos_27, '-99') = NVL(map.pos_27(+),NVL(l.pos_27, '-99')) AND NVL(l.pos_17, '-99') = NVL(map.pos_17(+),NVL(l.pos_17, '-99')) AND NVL(l.pos_18, '-99') = NVL(map.pos_18(+),NVL(l.pos_18, '-99')) AND NVL(l.pos_12, '-99') = NVL(map.pos_12(+),NVL(l.pos_12, '-99')) AND NVL(l.pos_16, '-99') = NVL(map.pos_16(+),NVL(l.pos_16, '-99')) AND NVL(l.pos_34, '-99') = NVL(map.pos_34(+),NVL(l.pos_34, '-99')) AND NVL(l.pos_43, '-99') = NVL(map.pos_43(+),NVL(l.pos_43, '-99')) AND NVL(l.pos_14, '-99') = NVL(map.pos_14(+),NVL(l.pos_14, '-99')) AND NVL(l.status_cd, '-99') = NVL(map.status(+),NVL(l.status_cd, '-99')) AND NVL(l.action_cd,'-99') = NVL(map.action_cd(+), NVL(l.action_cd,'-99')) AND NVL(l.sys,'-99') = NVL(map.sys(+), NVL(l.sys,'-99')) AND NVL(l.ind,'-99') = NVL(map.ind(+), NVL(l.ind,'-99')) )
How do I rewrite query so that I can use OR and the outer JOIN in the same query?Hello
It is one of several good reasons to use the ANSI join syntax. Move all the join conditions in the clause on, not the WHERE clause, and you do not use the sign +.
SELECT l.* FROM table1 l LEFT OUTER JOIN table2 map ON ( NVL(l.id, '-99') = COALESCE (map.id, l.id, '-99') AND l.TYPE = 'TKE' ) OR ( NVL (l.id, '-99') = COALESCE (map.id, l.id, '-99') AND NVL (l.type, '-99') = COALESCE (map.type), l.type, '-99') ...
Instead of nesting the NVL statements, use COALESCE, as illustrated above. It is independent of the issue of the join.
-
Hi all
I have issues with the help of ANSI LEFT JOIN compared to Oracle (+). Below test I did the same thing.
Here Query1 return all records of 4 same records regardless of emp_name = 'A' where as Query2 returns 2 records of ep_name = 'A' which is correct.create table emp (emp_id number(10), emp_name varchar2(50)); create table courses (course_id number(10), emp_id number(10), course_name varchar2(50)); INSERT INTO EMP values(1,'A'); INSERT INTO EMP values(2,'B'); INSERT INTO EMP values(3,'C'); INSERT INTO COURSES values(1,1,'ORACLE'); INSERT INTO COURSES values(2,1,'JAVA'); INSERT INTO COURSES values(3,3,'C#'); --*Query 1 SELECT a.*, b.* FROM EMP a LEFT JOIN COURSES b ON a.emp_id = b.emp_id AND a.emp_name = 'A' --*Query 2 SELECT a.*, b.* FROM EMP a, COURSES b where a.emp_id = b.emp_id(+) and a.emp_name = 'A'
Is this correct? I'm confused if you use the standard ANSI OUTER JOINS or not.
I am using Oracle 11g
Thank you.Change your AND WHERE, in the style of ANSI, select:
SELECT a.*, b.* FROM EMP a LEFT JOIN COURSES b ON a.emp_id = b.emp_id WHERE a.emp_name = 'A'
Filters in the clause are those who use the (+) in the Oracle syntax.
Filters WITHOUT (+) in the Oracle syntax should be in the WHERE clause using the ANSI syntax.Published by: Kim Berg Hansen on September 23, 2011 08:03
-
Show all dates between date range (time Dimension is left outer join)
All,
I did some research on this issue, but in all positions on date variables, date prompts and date filtering I have not seen one exactly to my question (perhaps that they are and I don't have my head around it properly yet).
My requirement of report is to allow a user to select a start date and an end of day. The report is expected to show the activity of these two days - AND display 0/null on days where there is no activity. This second part is where I am getting hung up.
The paintings in question are:
Timedim
EventFact
CustomerDim
My MDB is configured as follows:
Left outer join of Timedim EventFact
Inner join CustomerDim EventFact
If I run a report by selecting the DAYS of Timedim and an EventFact measure1 with range day 01/01/2010-31/12/2010... A record for each day and it looks perfect because of the left outer join between Timedim and CustomerDim.
But... If I add a CustomerDim field, Select TimeDim.DAY, CustomerDim.CUSTNAME, EventFact.MEASURE1, OBIEE returns only records for the days that have record EventFact.
This is due to the fact that the Timedim is always external joined in EventFact, but adding in fact CustomerDim OBIEE set up an inner join between tables that will only return data where there are data EventFact.
There is a way around it in this simple case, and that is to define the relationship between CustomerDim and EventFact as an outer join as well. This will give the desired effect (but an outer join between the two tables is not the real relationship) and I have add an extra dimension and add additional sources of logic to a single dimension in MDB it becomes complicated and messy.
Also, ive ruined with the definition of the conduct in the relationship table, etc... but he gave not the desired effect.
Has anyone ever met the need for force display all dates within a range specified with a fact table that does not have an entry for each date?
Thanks in advance.
K
Published by: user_K on April 27, 2010 11:32Hi there, the easiest way is to the LTS himself. Double-click your LTS, go to the tab with the column mappings. Make sure you have checked "show no mapped" column.
You should see your new dummy column in the list, in the central part of mapping (IE not the right) just enter 0, or launch the expression editor and enter 0 in there.
simple! -
SSRS for lack of outer join with the Oracle data source
It seems to be a problem with the Oracle driver used in the Reporting SERVICES query designer.
When you use an Oracle data source, if I create an outer join in the graphic designer, it automatically inserts '{OJ' before the join and '} ' after her. This is an incorrect syntax for Oracle and refuses to start. The curly braces and the JO editable in designer text, but if I go back to the graphic designer and immediately to reintegrate them.
Only, this has started to happen a year or two ago - before that it worked, but with the old (+) syntax.
Can it not be healed? It makes things very difficult.
-Geoff
Hi Geoff,
Thanks for posting in the Microsoft Community.
However, the question you posted would be better suited in the Forums of the Oracle Support; We recommend that you post your query in Oracle Support Forums to get help:
If you have any other questions or you need Windows guru, do not hesitate to post your questions and we will be happy to help you.
-
HELP SQL (auto / full outer join with date corresponding)
I'm having a hard time get this query nailed... hoping someone can help me sorted.
create table tab1 (identification number,
date of eff_date,
Code1 varchar2 (2),
Code2 varchar2 (2)
)
/
insert into tab1 values (2, to_date('2015-01-14','YYYY-MM-DD'), 'DAT', 'AS');
insert into tab1 values (2, to_date('2015-03-19','YYYY-MM-DD'), 'DAT', 'AS');
insert into tab1 values (2, to_date('2015-08-28','YYYY-MM-DD'), 'DAT', 'AS');
insert into tab1 values (2, to_date('2015-11-12','YYYY-MM-DD'), 'DAT', 'AS');
insert into tab1 values (2, to_date('2015-01-03','YYYY-MM-DD'), "DAT", "AE");
insert into tab1 values (2, to_date('2015-03-14','YYYY-MM-DD'), "DAT", "AE");
insert into tab1 values (2, to_date('2015-04-18','YYYY-MM-DD'), "DAT", "AE");
insert into tab1 values (2, to_date('2015-09-14','YYYY-MM-DD'), "DAT", "AE");
insert into tab1 values (2, to_date('2015-01-14','YYYY-MM-DD'), "DAT", "BS");
insert into tab1 values (2, to_date('2015-02-14','YYYY-MM-DD'), "DAT", "BS");
insert into tab1 values (2, to_date('2015-03-14','YYYY-MM-DD'), "DAT", "BS");
insert into tab1 values (2, to_date('2015-05-14','YYYY-MM-DD'), 'DAT', 'BE');
insert into tab1 values (3, to_date('2015-09-16','YYYY-MM-DD'), 'DAT', 'AS');
insert into tab1 values (3, to_date('2015-04-16','YYYY-MM-DD'), "DAT", "AE");
tab1
ID, date, code 1, code2
2. DID DAT 2015-01-14
2. DID DAT 2015-03-19
2. DID DAT 2015-08-28
2. DID DAT 2015-11-12
2 AE DAT 2015-01-03
2 AE DAT 2015-03-14
2 AE DAT 2015-04-18
2 AE DAT 2015-09-14
2 BS DAT 2015-01-14
2 BS DAT 2015-02-14
2 BS DAT 2015-03-14
BE DAT 2 2015-05-14
3. DID DAT 2015-09-16
3 AE DAT 2015-04-16
What I need to do...
1 auto join to match EI for each partition ID
2. THAT the date must be less than or equal to the date of the AE and when there is more then a line corresponding to this criterion has chosen the date of closest EI of the date of the ACE.
3. it must be a full outer join because I want to show all lines, even if it is not a match. There is a beginning, but not record end end gold but no record of departure
4. If there is an AE line for many AS lines (the SA date is less then equals the date of EI) then join this AE line to all 3 rows of ACE
5. the same rules for BS and BE.
result should look like this.
ID, date, code 1, id_1 code2, date_1, code1_1, code2_1
2 2015-01-14 DAT AS 2 AE DAT 2015-03-14
2 2015-03-19 DAT AS 2 AE DAT 2015-04-18
2 2015-08-28 DAT AS 2 AE DAT 2015-09-14
2 2015-11-12 DAT DID ZERO ZERO ZERO ZERO
NO NO NO NO 2 AE DAT 2015-01-03
2015-01-2 14 DAT BS 2 BE DAT 2015-05-14
2015-02-2 14 DAT BS 2 BE DAT 2015-05-14
2015 03-2 14 DAT BS 2 BE DAT 2015-05-14
3 2015-09-16 DAT DID ZERO ZERO ZERO ZERO
NO NO NO NO 3 AE DAT 2015-04-16
My attempt was somewhat along these lines (dealing only with SA / combos AE) but it does not manage the many scenarios one (req 4).
Select a.*, b.* from
(select row_number () on the rn (partition by a.id order a.eff_date), a.*)
of tab1 where a.code2 = 'AS') a
full outer join
(select row_number () on the rn (b.eff_date order by b.id partition), b.*)
tab1 b where b.code2 = 'Æ') b
on a.id = b.id
and a.rn = b.rn
and a.eff_date < = b.eff_date
Hello
owbdev99 wrote:
I'm having a hard time get this query nailed... hoping someone can help me sorted.
create table tab1 (identification number,
date of eff_date,
Code1 varchar2 (2),
Code2 varchar2 (2)
)
/
insert into tab1 values (2, to_date('2015-01-14','YYYY-MM-DD'), 'DAT', 'AS');
...
Thanks for posting the CREATE TABLE and INSERT. I know it can be a lot of trouble. You want to get answers that work, not you? Make sure that the statements you post too much work. Test (and, if necessary, attach) your statements before committing. You said code1 be VARCHAR2, but all the instructions insertion have values of 3 characters for code1.
You are on the right track, with an analytical function, but ROW_NUMBER solves this problem. 1 "THAT line" could correspond to the 1st, 2nd, 3rd or any other line 'AE' and vice versa. Try to use the analytical MIN function instead or ROW_NUMBER, like this:
WITH got_next_e_date AS
(
SELECT id, eff_date, code1, code2
MIN (CASE
WHEN SUBSTR (code2, 2) = 'E '.
THEN eff_date
END
) OVER (PARTITION BY ID.
, SUBSTR (code2, 1, 1)
ORDER BY eff_date DESC
) AS next_e_date
OF tab1
)
s AS
(
SELECT *.
OF got_next_e_date
"WHERE SUBSTR (code2, 2) s ="
)
e
(
SELECT *.
OF got_next_e_date
WHERE SUBSTR (code2, 2) = 'E '.
)
SELECT s.id
s.eff_date
s.code1
s.code2
e.id AS id_1
e.eff_date AS eff_date_1
e.code1 AS code1_1
e.code2 AS code2_1
S
FULL OUTER JOIN e ON s.id = e.id
AND s.next_e_date = e.eff_date
AND SUBSTR (s.code2, 1, 1) = SUBSTR (e.code2, 1, 1)
ORDER OF NVL (s.id, e.id)
, NVL (SUBSTR (s.code2, 1, 1)
, SUBSTR (e.code2, 1, 1)
)
s.eff_date
;
Out (as you asked):
ID EFF_DATE CODE1, CODE2 ID_1 EFF_DATE_1 CODE1_1 CODE2_1
--- ---------- ----- ----- ----- ---------- ------- -------
2 2015-01-14 DAT AS 2 AE DAT 2015-03-14
2 2015-03-19 DAT AS 2 AE DAT 2015-04-18
2 2015-08-28 DAT AS 2 AE DAT 2015-09-14
2. DID DAT 2015-11-12
2 AE DAT 2015-01-03
2015-01-2 14 DAT BS 2 BE DAT 2015-05-14
2015-02-2 14 DAT BS 2 BE DAT 2015-05-14
2015 03-2 14 DAT BS 2 BE DAT 2015-05-14
3. DID DAT 2015-09-16
3 AE DAT 2015-04-16
I guess code2 is always 2 characters, and the 2nd character is always ' or 'E '.
I assume that the combination [id, eff_date, code2] is unique.
If these assumptions are wrong, you need a few minor changes, but nothing big.
-
Bug with an outer join, or &; Analytics function (or rownum)
Hello
Seems to be a combination of an outer join, OR and rownum confuses the CBO.
First request is without rownum, the second is with rownum.
The second query expects 203 t lines and never ends. It should behave the same as query 1, with 24 M lines.
Remove the GOLD clause query 2 allows him to behave as a query 1, with 24 M lines.
We never saw it? Is there a solution?
SELECT * FROM message i LEFT JOIN (SELECT hi.message_id, hi.update_dt FROM message_hist hi) h ON (t.id = h.master_id AND(t.update_dt = h.update_dt OR h.update_dt <TO_DATE('150901','RRMMDD'))); ----------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 24M| 13G| 475G (2)|999:59:59 | | 1 | NESTED LOOPS OUTER | | 24M| 13G| 475G (2)|999:59:59 | | 2 | TABLE ACCESS FULL | MESSAGE | 8037K| 1318M| 29883 (2)| 00:06:59 | | 3 | VIEW | | 3 | 1302 | 59136 (2)| 00:13:48 | |* 4 | TABLE ACCESS FULL| MESSAGE_HIST | 3 | 168 | 59136 (2)| 00:13:48 | ----------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - filter("I"."MESSAGE_ID"="HI"."MESSAGE_ID" AND ("HI"."UPDATE_DT"<TO_DATE('150901','RRMMDD') OR "I"."UPDATE_DT"="HI"."UPDATE_DT")) ---------------- SELECT * FROM message i LEFT JOIN (SELECT hi.message_id, hi.update_dt , ROWNUM FROM message_hist hi) h ON (t.id = h.master_id AND(t.update_dt = h.update_dt OR h.update_dt <TO_DATE('150901','RRMMDD'))); ------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 203T| 112P| 475G (2)|999:59:59 | | 1 | NESTED LOOPS OUTER | | 203T| 112P| 475G (2)|999:59:59 | | 2 | TABLE ACCESS FULL | MESSAGE | 8037K| 1318M| 29883 (2)| 00:06:59 | | 3 | VIEW | | 25M| 10G| 59151 (2)| 00:13:49 | |* 4 | VIEW | | 25M| 10G| 59151 (2)| 00:13:49 | | 5 | COUNT | | | | | | | 6 | TABLE ACCESS FULL| MESSAGE_HIST | 25M| 1355M| 59151 (2)| 00:13:49 | ------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - filter("I"."MESSAGE_ID"="H"."MESSAGE_ID" AND ("I"."UPDATE_DT"="H"."UPDATE_DT" OR "H"."UPDATE_DT"<TO_DATE('150901','RRMMDD')))
RowNum in a subquery is supposed to ensure that the subquery is evaluated completely before filtering, otherwise, how could you go out rownum?
Your question is compounded because of the join condition that forces a level of nested loops, which means that the table should be fully analysed once for each line of conduct rowsource. You can either transform the join in an equijoin and allow a hash to run, or you join could materialize the subquery once.
Allow the hash join:
SELECT count (*)
Message FROM
LEFT JOIN (SELECT hi.message_id, hi.update_dt
ROWNUM
OF message_hist salvation) PM ON (i.message_id = h.message_id
AND i.update_dt = h.update_dt)
LEFT JOIN (SELECT hi.message_id, hi.update_dt
ROWNUM
OF message_hist salvation) h2 ON (i.message_id = h2.message_id
AND h2.update_dt<>
AND h2.update_dt <> i.update_dt)
/
----------------------------------------------------------------------------------------
| ID | Operation | Name | Lines | Bytes | Cost (% CPU). Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1. 66. 211 (1) | 00:00:01 |
| 1. GLOBAL TRI | | 1. 66. | |
|* 2 | EXTERNAL RIGHT HASH JOIN | | 800 | 52800 | 211 (1) | 00:00:01 |
|* 3 | VIEW | | 1. 22. 70 (0) | 00:00:01 |
| 4. COUNTY | | | | | |
| 5. TABLE ACCESS FULL | MESSAGE_HIST | 1. 22. 70 (0) | 00:00:01 |
|* 6 | EXTERNAL RIGHT HASH JOIN | | 800 | 35200. 141 (1) | 00:00:01 |
| 7. VIEW | | 1. 22. 70 (0) | 00:00:01 |
| 8. COUNTY | | | | | |
| 9. TABLE ACCESS FULL | MESSAGE_HIST | 1. 22. 70 (0) | 00:00:01 |
| 10. TABLE ACCESS FULL | MESSAGE | 800 | 17600 | 70 (0) | 00:00:01 |
----------------------------------------------------------------------------------------
Information of predicates (identified by the operation identity card):
---------------------------------------------------
2 - access("I".") MESSAGE_ID '= 'H2'.' MESSAGE_ID "(+))"
filter ("H2". "UPDATE_DT" (+)<>'I'. " ("' UPDATE_DT")
3 - filter("H2".") UPDATE_DT "(+)<>
6 - access("I".") "UPDATE_DT" ="H" UPDATE_DT "(+) AND"
"I"." ' MESSAGE_ID ' ="H" MESSAGE_ID "(+))"
Materialize the subquery:
WITH h AS (SELECT / * + MATERIALIZE * / hi.message_id, hi.update_dt)
ROWNUM
OF message_hist salvation)
SELECT count (*)
Message FROM
LEFT JOIN: ON (i.message_id = h.message_id
AND (i.update_dt = h.update_dt OR h.update_dt<>
----------------------------------------------------------------------------------------------------------
| ID | Operation | Name | Lines | Bytes | Cost (% CPU). Time |
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1. 22. 1740 (0) | 00:00:01 |
| 1. TRANSFORMATION OF THE TEMPORARY TABLE. | | | | |
| 2. LOAD SELECT ACE | SYS_TEMP_0FD9D6810_5B8F6E67 | | | | |
| 3. COUNT | | | | | |
| 4. TABLE ACCESS FULL | MESSAGE_HIST | 1. 22. 70 (0) | 00:00:01 |
| 5. GLOBAL TRI | | 1. 22. | |
| 6. NESTED EXTERNAL LOOPS | | 800 | 17600 | 1670 (0) | 00:00:01 |
| 7. TABLE ACCESS FULL | MESSAGE | 800 | 17600 | 70 (0) | 00:00:01 |
| 8. VIEW | | 1. | 2 (0) | 00:00:01 |
|* 9 | VIEW | | 1. 22. 2 (0) | 00:00:01 |
| 10. TABLE ACCESS FULL | SYS_TEMP_0FD9D6810_5B8F6E67 | 1. 22. 2 (0) | 00:00:01 |
----------------------------------------------------------------------------------------------------------
Information of predicates (identified by the operation identity card):
---------------------------------------------------
9 - filter("I".") ' MESSAGE_ID ' ="H" MESSAGE_ID' AND ('I'. "" "UPDATE_DT"="H" UPDATE_DT' OR
"H"." UPDATE_DT ".<>
You may need to change the first condition to make sure that you select the correct subquery.
-edit
Not able to view a plan but you can invade the second join condition select and then the result of a subquery with a predicate according to your requirement. This should delay the or rating and leave only an equijoin (although rowsource return may be slightly larger than the opposite).
-Second edition, it did not work exactly when I tried it.
A hybrid of the previous two plans with a slight modification of how he was imitating the GOLD:
WITH h AS (SELECT / * + MATERIALIZE * / hi.message_id, hi.update_dt)
ROWNUM Clotilde
OF message_hist salvation)
SELECT i.MESSAGE_ID
i.UPDATE_DT
COALESCE(h.message_id,h2.message_id) message_id
, COALESCE (h.update_dt, h2.update_dt) update_dt
Clotilde COALESCE (h.rown, h2.rown)
Message FROM
LEFT JOIN: ON (i.message_id = h.message_id
AND i.update_dt = h.update_dt)
LEFT JOIN: h2 WE (DECODE(h.message_id,,i.message_id) = h2.message_id - only try this if previous join returned NULL
AND h2.update_dt<>
/
--------------------------------------------------------------------------------------------------------
| ID | Operation | Name | Lines | Bytes | Cost (% CPU). Time |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1. 66. 8 (0) | 00:00:01 |
| 1. TRANSFORMATION OF THE TEMPORARY TABLE. | | | | |
| 2. LOAD SELECT ACE | SYS_TEMP_0FD9D6605_28F27F | | | | |
| 3. COUNT | | | | | |
| 4. TABLE ACCESS FULL | MESSAGE_HIST | 150. 3300 | 2 (0) | 00:00:01 |
| 5. GLOBAL TRI | | 1. 66. | |
|* 6 | EXTERNAL RIGHT HASH JOIN | | 10497. 676K | 6 (0). 00:00:01 |
|* 7 | VIEW | | 150. 3300 | 2 (0) | 00:00:01 |
| 8. TABLE ACCESS FULL | SYS_TEMP_0FD9D6605_28F27F | 150. 3300 | 2 (0) | 00:00:01 |
|* 9 | OUTER HASH JOIN | | 328. 14432 | 4 (0) | 00:00:01 |
| 10. TABLE ACCESS FULL | MESSAGE | 200 | 4400 | 2 (0) | 00:00:01 |
| 11. VIEW | | 150. 3300 | 2 (0) | 00:00:01 |
| 12. TABLE ACCESS FULL | SYS_TEMP_0FD9D6605_28F27F | 150. 3300 | 2 (0) | 00:00:01 |
--------------------------------------------------------------------------------------------------------Information of predicates (identified by the operation identity card):
---------------------------------------------------6 - access("H2".") MESSAGE_ID "(+) = DECODE (TO_CHAR ('H'". "))" MESSAGE_ID"), NULL, 'I '. (("' MESSAGE_ID '))
7 - filter("H2".") UPDATE_DT "(+)<>
9 - access("I".") "UPDATE_DT" ="H" UPDATE_DT "(+) AND 'I'." "" ' MESSAGE_ID '="H" MESSAGE_ID "(+))"(This plan is another system if costs are not comparable)
-
Outer join does not not as expected left
Hi all
I have it here are three tables with values. Mentioned the under outer join query does not and behave like the inner query.
CREATE TABLE RET_FUND_FEE
(
NPTF VARCHAR2 (8 CHAR),
TPART VARCHAR2 (4 CHAR)
);
CREATE TABLE PART_PTF
(
Mf_Id VARCHAR2 (6 CHAR) NOT NULL,
TPARTS VARCHAR2 (4 CHAR) NOT NULL
);
CREATE TABLE TFC_FUNDS
(
NPTF VARCHAR2 (8 CHAR) NOT NULL,
MULTIFONDS_ID VARCHAR2 (6 CHAR)
);
INSERT INTO RET_FUND_FEE VALUES('111','A');
INSERT INTO RET_FUND_FEE VALUES('111','D');
INSERT INTO RET_FUND_FEE VALUES('111','E');
INSERT INTO PART_PTF VALUES ('MF1', 'A');
INSERT INTO PART_PTF VALUES ('MF1', 'B');
INSERT INTO PART_PTF VALUES('MF1','C');
INSERT INTO TFC_FUNDS VALUES('111','MF1');
INSERT INTO TFC_FUNDS VALUES('111','MF1');
INSERT INTO TFC_FUNDS VALUES('111','MF1');
SELECT A.TPART, B.TPARTS, A.NPTF, B.Mf_Id, C.MULTIFONDS_ID, C.NPTF
OF RET_FUND_FEE A, PART_PTF B, TFC_FUNDS C
WHERE A.NPTF = C.NPTF
AND C.MULTIFONDS_ID = B.Mf_Id
AND A.TPART = B.TPARTS (+)
AND C.MULTIFONDS_ID = 'MF1 '.
AND C.NPTF = '111'
Here, I expect all records in the RET_FUND_FEE table that I am using outer join.
But I'm only corresponding chronogram RET_FUND_FEE, PART_PTF as an inner join. Can you get it someone please let me know what lack us.
Is my version of oracle 11g
SELECT
A.TPART, B.TPARTS, A.NPTF, B.Mf_Id, C.MULTIFONDS_ID, C.NPTF
Of
PART_PTF B
Join
C TFC_FUNDS
on (C.MULTIFONDS_ID = B.Mf_Id
AND C.MULTIFONDS_ID = 'MF1 '.
AND C.NPTF = '111'
)
right outer join
RET_FUND_FEE HAS
on (A.TPART = B.TPARTS
and A.NPTF = C.NPTF) - added as correction
TPART TPARTS NPTF MF_ID MULTIFONDS_ID NPTF A A 111 MF1 MF1 111 A A 111 MF1 MF1 111 A A 111 MF1 MF1 111 E - 111 - - - D - 111 - - - or
SELECT A.TPART, d.TPARTS, A.NPTF, d.Mf_Id, d.MULTIFONDS_ID, d.NPTF
OF RET_FUND_FEE HAS
, (
Select
*
PART_PTF b, TFC_FUNDS C
where B.Mf_Id = C.MULTIFONDS_ID
AND C.MULTIFONDS_ID = 'MF1 '.
AND C.NPTF = '111'
) d
WHERE A.TPART = D.TPARTS (+)
and A.NPTF = D.NPTF (+) - added as a correction
Sorry had to correct the syntax oracle solution.
The first one was bad because it would return also B lines that have no match in C.
Sorry a correction more on these two approaches, missed the second predicate.
-
Oracle: Use LEFT OUTER JOIN, but convert the data to an external list
Hello, all,.
I know it can be done; I just don't remember how I got it done, oh there are so many years.
Assumes that the tables exist for groups and individuals. People can belong to several groups.
SELECT g.groupName, p.lastName || ', ' || p.firstName as fullName FROM groups g LEFT OUTER JOIN groupPersonAssociation gpa ON gpa.groupID = g.groupID LEFT OUTER JOIN person p ON p.personID = gpa.personID ORDER BY g.groupName, fullName
This gives us:
Group One Alpha, Daniel Group One Bravo, Charles Group One Charlie, Chuck Group Two Beta, Alpha Group Two Delta, Bonnie Group Three Echo, Bunny Group Three Golf, Samuel Group Three November, Stan
How word the SQL to get the data as:
Group One Alpha, Daniel | Bravo, Charles | Charlie, Chuck Group Two Beta, Alpha | Delta, Bonnie Group Three Echo, Bunny | Golf, Samuel | November, Stan
V/r,
^_^
I finally thought to it. I was using incorrect keywords on Google.
SELECT g.groupName, LISTAGG(p.lastName || ', ' || p.firstName,' | ') WITHIN GROUP (ORDER BY g.groupName) "fullName" FROM groups g LEFT OUTER JOIN groupPersonAssociation gpa ON ggpa.groupID = g.groupID LEFT OUTER JOIN person p ON p.personID = gpa.personID GROUP BY g.groupName ORDER BY g.groupName, fullName
Just in case someone else is going through this same desire.
HTH,
^_^
-
using outer joins if the two column is null? Use only (+)
Hi all
create the table xxc_tr_num (tl_number number, tr_no number tl_no_id);
insert into xxc_tr_num values (123,100,222);
insert into xxc_tr_num values (124,100,333);
create the table xxc_od_tab (tl_number number, tl_id number);
insert into xxc_od_tab values (123,001);
insert into xxc_od_tab values (null, null);
create table xxc_oth_tab (name varchar2 (10), number of tl_id);
insert into xxc_oth_tab values('abc',,001);
insert into xxc_oth_tab values (null, null);
Wait it out put
tr_no tl_no_id name
100 222 abc
100 333
using outer joins if the two column is null? use only please of outer joins
And I tried to use outer joins on both tl_id column but not get values and I use have County (tr_no ) > 1
Rajesh123 wrote:
Thank you Kiss it is not possible to use having clause?
You need to understand the functioning of the group. If you will not be asked this question.
Check this box
SQL> select tr_no, 2 tl_no_id, 3 count(*) 4 from xxc_tr_num a, 5 xxc_od_tab b, 6 xxc_oth_tab c 7 where a.tl_number = b.tl_number(+) 8 and b.tl_id = c.tl_id(+) 9 group 10 by tr_no 11 , tl_no_id; TR_NO TL_NO_ID COUNT(*) ---------- ---------- ---------- 100 333 1 100 222 1
See what returns the count? You have grouped according to TR_NO and TL_NO_ID. You must take into consideration the TL_NO_ID just put COUNT (TR_NO) does not increase the NUMBER of the whole group. To get the NUMBER on the whole group, I used the analytical function and did. Like this, see the number of the analytical function here
SQL> select tr_no, 2 tl_no_id, 3 count(*), 4 count(*) over(partition by tr_no) 5 from xxc_tr_num a, 6 xxc_od_tab b, 7 xxc_oth_tab c 8 where a.tl_number = b.tl_number(+) 9 and b.tl_id = c.tl_id(+) 10 group 11 by tr_no 12 , tl_no_id; TR_NO TL_NO_ID COUNT(*) COUNT(*)OVER(PARTITIONBYTR_NO) ---------- ---------- ---------- ------------------------------ 100 222 1 2 100 333 1 2
So to answer your question, yes you can't do in the HAVING clause...
-
Hi all
I use under version
Connected to Oracle Database 11g Express Edition Release 11.2.0.2.0
SQL > SELECT E.ENAME,.
2 D.DEPTNO,
3 D.LOC
4. TO EMP E,.
DEPT 5 D
6. WHERE = E.DEPTNO D.DEPTNO (+);
ENAME, DEPTNO LOC
---------- ------ -------------
DALLAS SMITH 20
ALLEN 30 CHICAGO
WARD 30 CHICAGO
20 DALLAS JONES
MARTIN 30 CHICAGO
BLAKE 30 CHICAGO
CLARK 10 NEW YORK
SCOTT 20 DALLAS
THE 10 NEW YORK KING
TURNER 30 CHICAGO
20 DALLAS ADAMS
JAMES 30 CHICAGO
FORD 20 DALLAS
MILLER 10 NEW YORK
40 BOSTON
15 selected lines
-----------------------------------------------------------------------------------------------------------------------------
SQL > SELECT E.ENAME,.
2 D.DEPTNO,
3 D.LOC
4. TO EMP E
5 LEFT OUTER JOIN
D 6 DEPT
7. THE E.DEPTNO = D.DEPTNO;
ENAME, DEPTNO LOC
---------- ------ -------------
MILLER 10 NEW YORK
THE 10 NEW YORK KING
CLARK 10 NEW YORK
FORD 20 DALLAS
20 DALLAS ADAMS
SCOTT 20 DALLAS
20 DALLAS JONES
DALLAS SMITH 20
JAMES 30 CHICAGO
TURNER 30 CHICAGO
BLAKE 30 CHICAGO
MARTIN 30 CHICAGO
WARD 30 CHICAGO
ALLEN 30 CHICAGO
14 selected lines
My doubt is both are same query is the same, is in ansi format and is in the format of the Oracle,.
but the results are different.
For the first query null is coming for unmatched records in the dept table
but in the second query, it does not come
Thank you
Hello
2947022 wrote:
Hi all
I use under version
Connected to Oracle Database 11g Express Edition Release 11.2.0.2.0
SQL > SELECT E.ENAME,.
2 D.DEPTNO,
3 D.LOC
4. TO EMP E,.
DEPT 5 D
6. WHERE = E.DEPTNO D.DEPTNO (+);
ENAME, DEPTNO LOC
---------- ------ -------------
DALLAS SMITH 20
ALLEN 30 CHICAGO
WARD 30 CHICAGO
20 DALLAS JONES
MARTIN 30 CHICAGO
BLAKE 30 CHICAGO
CLARK 10 NEW YORK
SCOTT 20 DALLAS
THE 10 NEW YORK KING
TURNER 30 CHICAGO
20 DALLAS ADAMS
JAMES 30 CHICAGO
FORD 20 DALLAS
MILLER 10 NEW YORK
40 BOSTON
15 selected lines
-----------------------------------------------------------------------------------------------------------------------------
SQL > SELECT E.ENAME,.
2 D.DEPTNO,
3 D.LOC
4. TO EMP E
5 LEFT OUTER JOIN
D 6 DEPT
7. THE E.DEPTNO = D.DEPTNO;
ENAME, DEPTNO LOC
---------- ------ -------------
MILLER 10 NEW YORK
THE 10 NEW YORK KING
CLARK 10 NEW YORK
FORD 20 DALLAS
20 DALLAS ADAMS
SCOTT 20 DALLAS
20 DALLAS JONES
DALLAS SMITH 20
JAMES 30 CHICAGO
TURNER 30 CHICAGO
BLAKE 30 CHICAGO
MARTIN 30 CHICAGO
WARD 30 CHICAGO
ALLEN 30 CHICAGO
14 selected lines
My doubt is both are same query is the same, is in ansi format and is in the format of the Oracle,.
but the results are different.
For the first query null is coming for unmatched records in the dept table
but in the second query, it does not come
Thank you
In fact, these requests are not the same.
The first is to find all the lines of the Department, with the corresponding lines of PGE (when there are). This is equivalent to «FROM dept LEFT OUTER JOIN emp...» ».
The second is to find all the rows in the emp of the lines of the Department (when there are any). This is equivalent to «...» WHERE e.deptno = d.deptno (+).
Maybe you are looking for
-
Automatic download extensions do not work
I use the extension "Download 2.5.8 ranking" somewhat, specifically to download images, but since I updated Firefox to version 23.0 this extension no longer works. When I right-click on an image that I want to automatically record, then select "Save
-
Processor Intel® Celeron® 925 64-bit cpu 4mg of ram index why 3.3
Processor Intel® Celeron® 925 64-bit cpu 4mg of ram index why 3.3
-
I don't have a windows recovery disk and my computer is affected by virus now, I am also not able to downloat antivirus because some files are missing please notify
-
The program cannot start because MSVCR100.dll is missing from your computer. Try reinstalling the program to fix this problem. I get following error when I try to open the computer management in windows 7, the error is as follows. The program cannot
-
Remote Desktop screen does not minimize.
I have windows 7 on my laptop and windows xp on the remote computer that I log on. I'm not able to minimize the screen of the remote computer in a single click. I have to click 10 times to make it to minimize. This problem started since I upgraded my