Outer join in view criteria: how to ?
Hello,
I have to create a VO for a LOV. I created in this VO a ViewCriteria to pass variables for the query.
The problem is that for one of this variable I have to set the clause as an outer join.
JDeveloper creates:
SELECT MyView1.Item, MyView2.Code
FROM MyView1, MyView2
WHERE MyView1.ID = MyView2.EXT_ID (+)
AND MyView1.Item = :TheItem
AND MyView2.Code = :TheCodebut I need something like:
SELECT MyView1.Item, MyView2.Code
FROM MyView1, MyView2
WHERE MyView1.ID = MyView2.EXT_ID (+)
AND MyView1.Item = :TheItem
AND :TheCode = MyView2.Code (+)
ADFboy wrote:
this is optional parameter value, in the view criteria windows is this option....
AdfBoyNo, this parameter is not optional because, in the call of the LOV it will be always set.
But the query without the outer join returns too few rows...
I tried to find where to "intercept" this programmatically, but I'm failing doing this. :(
I'll have the same problem with another field, not for a LOV but to get the value of an attribute of a VO.
Even in advanced mode the Where clause can't have parameters...
Similar Messages
-
Hi everybody
I use jdeveloper 11.1.1.6.0
I want to create outer join in view criteria, so I had to override getCriteriaItemClause method in ViewObjImpl.java
my query is like this :
SELECT t1.row_no, t2.type FROM table_1 t1 , table_2 t2
WHERE t1.row_no(+) = t2.row_no
and t1.user_Id(+) = :bindVar
table_1(row_no, user_Id )
table_2(row_no,type)
the part " t1.user_Id(+) = :bindVar " should be put in the view criteria
the method:
@Override
public String getCriteriaItemClause(ViewCriteriaItem viewCriteriaItem) {
String newQeury =this.getEntityDef(0).getAliasName() + "." + viewCriteriaItem.getColumnName() + "(+) = :bindVar ";
return newQeury;
but when I run the view criteria the exception below raises:
oracle.jbo.expr.JISyntaxError: JBO-36000: An unexpected expression token is found.
when I remove sign "(+)" from newQeury
String newQeury =this.getEntityDef(0).getAliasName() + "." + viewCriteriaItem.getColumnName() + "= :bindVar "; // remove sign '(+)' before = :bindVar
the exception below raises
JBO-29000: Unexpected exception caught: oracle.jbo.expr.JIEvalException, msg=JBO-25077: Name t1 not found in the given object: ViewRow [oracle.jbo.Key[5 1 5 ]].
HabibThis is a duplicate of https://forums.oracle.com/thread/2577092
Please don't post your questions multiple times.
A possible solution posted to the original thread.
Timo -
Hi there,
sorry about the big post but I am wondering if someone could help me with this. I dont seem to be able to figure out what I am doing wrong here:
I've created a function that merges a number of lines of text into one row, the function works fine if I call it directly:
CREATE FUNCTION "LONG_TEXT" (code IN VARCHAR2, inc_no IN VARCHAR2)
RETURN VARCHAR2 IS
text_full VARCHAR2(32767);
BEGIN
FOR r IN ( SELECT bo_text
FROM text_table
WHERE SUBSTR(bo_key,1,4) = code
AND SUBSTR(bo_key,5,10) = inc_no
AND bo_text_code = 'IT'
ORDER BY LINE_NO)
LOOP
text_full := text_full || ' ' || trim(r.bo_text);
END LOOP;
RETURN trim(text_full);
END long_text;
I've called the function in a view - works fine when I call it directly:
CREATE OR REPLACE VIEW "EEV097_IT" ("CODE","INC_NO","BO_TEXT") AS SELECT DISTINCT SUBSTR(bo_key,1,4) AS code,
SUBSTR(bo_key,5,10) AS inc_no,
long_text(SUBSTR(bo_key,1,4),SUBSTR(bo_key,5,10)) AS bo_text
FROM text_table
WHERE bo_text_code = 'IT'
Then I've joined the view to another table. This statement actually works:
SELECT
EEV097_IT.CODE,
EEV097_IT.BO_TEXT,
EEV097_IT.INC_NO,
INC_DIM.REV_OCC_DATE
FROM
INC_DIM
LEFT OUTER JOIN
EEV097_IT ON EEV097_IT.CODE=INC_DIM.CODE AND
EEV097_IT.INC_NO=INC_DIM.INC_NO
WHERE
INC_DIM.BO_USER_ID = 'L83321' AND
INC_DIM.REV_OCC_DATE BETWEEN '19/FEB/07' AND '23/FEB/07'
INC_DIM.INC_NO = '1234';
but as soon as it take this line "INC_DIM.INC_NO = '1234'" out of the where clause or add a second inc_no something like INC_DIM.INC_NO in ('1234','2345'); oracle hangs when I execute this statement - At the end of the day I dont want to specify a inc_no in the where clause at all - The expected result is quite small just about 10 rows I am using oracle version 11.1.0.6.
If someone has an idea please let me - there would be one work around to put the view as a nested selected into the statement that works fine, but I can't use it. I basically need to end up with a view that I can join to the other table like I did above - so the fix needs to be in the view or in the function.
thanks
jessPlease provide more details as mentioned in When your query takes too long ... thread
-
View Criteria - how to show the VO filtered differently at a time
My requirement is something like this-
I have a detailsVO which is a join of say employee and department table
I need to show the VO in such a way that-
department1
detailsVO <filtered rows for department1)
department2
detailsVO <filtered rows for department2)
department3
detailsVO <filtered rows for department3)
Here each filtered VO is to be show in different UI table
How do I achieve this? Any suggestions? If I use a VOCriteria with :BindDepartment, how do I bind the same detailsVO to show the details?
Please advise.How about using a tree table?
Or you may want to look at http://tompeez.wordpress.com/2011/12/29/jdeveloper-11-1-2-1-cascading-tables/ which uses two cascading tables.
Timo -
Granting SELECT to user on VIEW with FULL OUTER JOIN fails?
I have a quandary.
Using Oracle 9i, I have created a simple view. When I perform a count on it, rows are returned.
However, when I grant SELECT access to another user, they can't see the VIEW. The VIEW has a FULL OUTER JOIN operation in it.
When I do the same thing using a regular join, it works.
Any ideas why, please?
SQL> conn ifsinfo/******@DB
Connected.
SQL> ed
Wrote file afiedt.buf
1 create view mctest3 as
2 select
3 vc.idcus ,
4 ci.customer_id
5 from
6 ifsapp.vmo_company vc
7 full outer join
8 ifsapp.customer_info ci
9 on
10* vc.custno = ci.customer_id
SQL> /
View created.
SQL> select count(*) from mctest3;
COUNT(*)
73994
SQL> GRANT SELECT ON MCTEST3 TO IFSAPP WITH GRANT OPTION;
Grant succeeded.
SQL> CONN IFSAPP/******@DB
Connected.
SQL> select count(*) from IFSINFO.MCTEST3;
select count(*) from IFSINFO.MCTEST3
ERROR at line 1:
ORA-00942: table or view does not existbut with regular join:
SQL> conn ifsinfo/******@DB
Connected.
SQL> create view mctest4 as
2 select
3 vc.idcus ,
4 ci.customer_id
5 from
6 ifsapp.vmo_company vc, ifsapp.customer_info ci
7 where vc.custno = ci.customer_id;
View created.
SQL> select count(*) from mctest4;
COUNT(*)
44269
SQL> GRANT SELECT ON MCTEST4 TO IFSAPP WITH GRANT OPTION;
Grant succeeded.
SQL> conn ifsapp/******@DB
Connected.
SQL> select count(*) from IFSINFO.MCTEST4;
COUNT(*)
44269Hi,
>>SQL> conn ifsinfo/******@DB
Connected.
SQL> ed
Wrote file afiedt.buf
1 create view mctest3 as
2 select
3 vc.idcus ,
4 ci.customer_id
5 from
6 ifsapp.vmo_company vc
7 full outer join
8 ifsapp.customer_info ci
9 on
10* vc.custno = ci.customer_id
SQL> /
According to Note:244315.1, it is not possible to make a FULL OUTER JOIN on views owned by another user at the 9i version of Oracle. As above, do not use FULL OUTER JOIN on views owned by another user. Try to use outer join operator (+), and/or UNIONS instead.
Cheers -
Oracle 8i -multiple LEFT OUTER JOIN
Hi,
I have to convert some stored procedure from Sql Server to Oracle 8i where I have multiple LEFT OUTER JOIN on a table. Because Oracle 8i accept only one outer join on a table how can I convert this:
select a.id, b.id
from test as a LEFT JOIN test1 b ON a.id(+)=b.id
and a.display(+)=b.display
and a.name(+)='Done';
Thanks.FROM test a LEFT JOIN test1 b ON b.key = a.keyis equivalent to
FROM test a, test1 b WHERE b.key(+) = a.keyThere is a restriction (when using the "(+)" syntax) that a table may be outer-joined to at most one other table, but that does not prevent you from having multiple join conditions between those two tables.
From your example I'm not sure whether you need this:
SELECT a.id, b.id
FROM test a
, test1 b
WHERE a.name = 'Done'
AND b.id (+)= a.id
AND b.display (+)= a.display;or this:
SELECT a.id, b.id
FROM test1 b
, test a
WHERE a.id (+)= b.id
AND a.display (+)= b.display;
WHERE a.name (+)= 'Done'; -
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. -
Outer join with BETWEEN clause
Hi All,
I have 2 tables (A and B) which i need to join. I need all records from table A and matching records from the table B. below is the structure.
TABLE A (total rows = 10)
ROW_WID
GL_DATE
LOCATION_CODE
TABLE B (total = 7)
ROW_WID
START_DATE
END_DATE
LOCATION_CODE
Initially, we were asked to join based on location_code. In the table B, some of the LOCATION_CODE are missing, which is present in table A.
We wrote below query
SELECT A.*, B.START_DATE, B.END_DATE
FROM A, B
WHERE A.LOCATION_CODE = B.LOCATION_CODE (+)
This gives 10 records, where 3 records have START_DATE and END_DATE NULL. because of outer join
It gave all records from the A table. It worked fine. Now i need to add one more condition where A.GL_DATE between B.START_DATE and B.END_DATE
If i write this
SELECT A.*, B.START_DATE, B.END_DATE
FROM A, B
WHERE A.LOCATION_CODE = B.LOCATION_CODE (+)
AND A.GL_DATE BETWEEN B.START_DATE and B.END_DATE
This gives me only 7 records. IS IT POSSIBLE TO ADD OUTER JOIN with BETWEEN clause.Hi All,
I'm in a similar situation,
I have a complex query, everything is working fine, except this part (I will simplify everything, removing other stuffs because I need help only on the following condition)
SELECT *
from transaction t, card c
where c.card_id = t.card_id (+)
and t.trn_date between to_date ('01/01/2012','dd/mm/yy') and ('01/01/2013,'dd/mm/yy')
How could i OUTER JOIN the between condition?
I tried with
and t.trn_date between to_date ('01/01/2012','dd/mm/yy') (+) and ('01/01/2013','dd/mm/yy') (+)
but returns a "missing expression" error.
Surely I'm missing some stupid thing about it, could you help me on this? (probably because I'm talking about parameters and I cannot put the outer join on a value)
How can I rewrite the condition in order to satisfy what I'm trying to accomplish?
Thanks in Advance,
Alex
Edited by: 981667 on 14-gen-2013 4.23
Edited by: 981667 on 14-gen-2013 4.24 -
Hyperlinks bump me out of Slideshow View
Hi.
I have a Keynote presentation that has links to another Keynote presentation. When I click the link in Slideshow view, the other presentation opens but I get bumped out of Slideshow view. How do I keep this from happening?
And once I have the linked presentation open, how do I smoothly go back to my original presentation?
Many thanks!duplicate post - see the reply in your original
-
Programmatically adding two view criteria
Hello,
I am using Jdev version 12.1.2.0.0 and i am trying to apply two view criteria to a view object:
ViewObject vo = ...
ViewCriteria vc1 = vo.createViewCriteria();
ViewCriteriaRow vcr1 = vc1.createViewCriteriaRow();
vcr1.setAttribute(smt,smt);
vc1.add(vcr1);
ViewCriteria vc2 = vo.createViewCriteria();
ViewCriteriaRow vcr2 = vc2.createViewCriteriaRow();
vcr2.setAttribute(smt,smt);
vc2.add(vcr2);
vo.applyViewCriteria(vc1);
vo.applyViewCriteria(vc2,true);
vo.executeQuery();
I don't know why, but it executes just the second view criteria.
Thank you in advanced.From the dos it looks like you add multiple rows to one view criteria but can only apply one view criteria
public static void demoCriteria(ApplicationModule appMod)
// Create and populate criteria rows to support query-by-example.
ViewObject empView = appMod.createViewObject("Emp", "mypackage1.EmpView");
ViewCriteria vc = empView.createViewCriteria();
ViewCriteriaRow vcRow = vc.createViewCriteriaRow();
// ViewCriteriaRow attribute name is case-sensitive.
// ViewCriteriaRow attribute value requires operator and value.
// Note also single-quotes around string value.
ViewCriteriaItem jobItem = vcRow.ensureCriteriaItem("Job");
jobItem.setOperator("=");
jobItem.getValues().get(0).setValue("MANAGER");
vc.add(vcRow);
vcRow = vc.createViewCriteriaRow();
ViewCriteriaItem salItem = vcRow.ensureCriteriaItem("Sal");
salItem.setOperator(">");
salItem.getValues().get(0).setValue(new Integer(2500));
vc.add(vcRow);
empView.applyViewCriteria(vc);
// Multiple rows are OR-ed in WHERE clause.
System.out.println("Demo View Criteria");
// Should print employees that are MANAGER or have Sal > 2500
QueryDemo.printViewObject(empView);
Timo -
Multiple LEFT OUTER JOIN on Oracle 8i
Hi,
I have to convert some stored procedure from Sql Server to Oracle 8i where I have multiple LEFT OUTER JOIN on a table. Because Oracle 8i accept only one outer join on a table how can I convert this:
select a.id, b.id
from test as a LEFT JOIN test1 b ON a.id(+)=b.id
and c.display(+)=b.display
and c.name(+)='Done';
Thanks.Rewrite as:
select a.id, b.id
from test, test1 b
WHERE a.id(+)=b.id
and a.display(+)=b.display
and a.name(+)='Done';
Though I would lose the (+) in a.name(+) = 'Done' unless you want every name. -
Hi,
Our Team have created so many Inactive view ( Attr, Ana, Cal) and they didn't deleted those view. I want to list out all inactive view. How to find out those view.
Regards,
KamruzThanks for you your mail. I cross checked once again.
No INACTIVE _OBJECT is displaying under this schema.
Only below 4 tables are showing.
ACTIVE_OBJECT
ACTIVE_OBJECTCROSSREF
ACTIVE_OBJECT_TEXT_CONTENT
ACTIVE_TAGS -
How to outer join within a view link from (VO-VL-VO)
I've got a table that stores the values of pre-defined attributes.
I'd like to create an advancedTable region that shows all of the attributes with or without values, in my view object i have....
select attribute, value
from attributes, values
where attributes.attribute_id = values.attribute_id (+)
This is working, but a have another view object that is the master and this is the details.
How can I do an outer join on the view link from master to detail? A simple (+) in the where condition does not do the trick.
If I try anything fancy within the view link, I get a JBO-27122.
Thank you,
Jerry.Understand the concept of VL. Vl is nothing but a link between two VOs, with one VO row column serve as binding column for another VO.If u understand this u go to VL wizard and make VL declaratively. If not, refer to dev guide to know about VL.
--Mukul -
How can I crate a view with tables which require "Left outer join"?
Hi guys,
how can I define a view with tables which require "Left outer join"?. In SE11 "View",->tab "Join condition", it seems that it valid only for "Inner Join".
Please give me some hint.
Thanks in advance.
Regards,
LiyingHi
Inner Join and Outer Join
The data that can be selected with a view depends primarily on whether the view implements an inner join or an outer join.
With an inner join, you only get the records of the cross-product for which there is an entry in all tables used in the view.
With an outer join, records are also selected for which there is no entry in some of the tables used in the view. (ABAP allows left outer join.)
The data that can be selected with a view depends primarily on whether the view implements an inner join or an outer join. -
Create a view that 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
, FILLER VARCHAR2(100) NOT 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 ) A
, (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
, (select round(DBMS_RANDOM.VALUE * 400,2) "ITEM_AMT" from dual) F
CREATE UNIQUE INDEX MY_PAY_ITEMS ON MY_PAY_ITEMS (EMP, PAY_PRD, KEY1, KEY2, LN_ITEM)
CREATE TABLE MY_ITEM_DISPLAY
( DISPLAY_CODE VARCHAR2(4) NOT NULL
, SEQUENCE NUMBER(2) NOT 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 payslip line items. It has a total size of 500,000,000 rows.
EMP is the unique employee id, We have approx 200,000 employees (with approx 50,000 being active today).
PAY_PRD is a weekly pointer (2010-01, 2010-02 ... 2010-52), we have data from 2004 and are adding a new pay period every week. 2010-01 is defined as the first monday in 2010 to the first sunday in 2010 etc.
KEY1 is an internal key, it tracks the timeline within the pay period.
KEY2 is a child of KEY1, it tracks the sequence of events within KEY1.
LN_ITEM is the actual pay item that resulted from the event on average a person generates 20 rows per event. Note that in this example everybody gets the same LN_ITEM values, but in practice it is 20 selected from 300
ITEM_AMT is the net pay for the line item.
FILLER is an assortment of fields that are irrelevant to this question, but do act as a drag on any row loads.
MY_ITEM_DISPLAY is a table that describes how certain screens should display items. The screen itself is a 4 column grid, with the contents of the individual cells being defined as a lookup of LN_ITEMS to retrieve the relevant LN_AMT.
We have an application that receives a DISPLAY_CODE and an EMP. It automatically creates a sql statement along the lines of
SELECT * FROM MY_VIEW WHERE DISPLAY_CODE = :1 AND EMP = :2
and renders the output for the user.
My challenge is that I need to rewrite MY_VIEW as follows:
1) Select the relevant rows from MY_ITEM_DISPLAY where DISPLAY_CODE = :1
2) Select the relevant all rows from MY_PAY_ITEMS that satisfy the criteria
a) EMP = :2
b) PAY_PRD = (most recent one for EMP as at sysdate, thus if they last got paid in 2010-04 , return 2010-04)
c) KEY1 = (highest key1 within EMP and PAY_PRD)
d) KEY2 = (highest key2 within EMP, PAY_PRD and KEY1)
3) I then need to cross reference these to create a tabular output
4) Finally I have to return a line of 0's where no LN_ITEMs exist ( DISPLAY_CODE 01, sequence 40 contains impossible values for this scenario)
The below query does 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"
FROM MY_ITEM_DISPLAY A, MY_PAY_ITEMS B
WHERE B.PAY_PRD = '2010-03'
GROUP BY A.DISPLAY_CODE, B.EMP, A.SEQUENCE)
WHERE DISPLAY_CODE = '01'
AND EMP = '0000011'
ORDER BY SEQUENCE
My questions
1) How do I do the PAY_PRD, KEY1, KEY2 constraint, can I use some form of ROW_NUMBER() OVER function ?
2) How do I handle the fact that none of the 4 column LN_ITEMS may exist (see sequence 40, none of those line items can exist)... Ideally the above SQL should return
01, 0000011, 10, <some number>, <some number>, <some number>, <some number>
01, 0000011, 20, <some number>, <some number>, <some number>, <some number>
01, 0000011, 30, <some number>, <some number>, <some number>, <some number>
01, 0000011, 40, 0 , 0 , 0 , 0
I tried a UNION, but his prevented the view from eliminating the bulk of the MY_PAY_ITEMS rows, as it resolve ALL of MY_PAY_ITEMS instead of just retrieving rows for the one EMP passed to the view. The same seems to be true for any outer joins.Hi, if i understood you properly, you need :
select nvl(q.display_code,lag(q.display_code) over (order by rownum)) display_code,
nvl(q.emp,lag(q.emp) over (order by rownum)) emp,
m.s,
nvl(q.COL1,0) COL1,
nvl(q.COL2,0) COL2,
nvl(q.COL3,0) COL3,
nvl(q.COL4,0) COL4,
nvl(PAY_PRD,lag(q.PAY_PRD) over (order by rownum)) PAY_PRD,
nvl(KEY1,lag(q.KEY1) over (order by rownum)) KEY1,
nvl(KEY2,lag(q.KEY2) over (order by rownum)) KEY2
from(
select d.display_code,
t.emp,
d.sequence,
max(DECODE(t.LN_ITEM, d.COLUMN_ITEM1, t.ITEM_AMT, 0)) keep (dense_rank first order by to_date(t.pay_prd,'yyyy-mm') desc ) "COL1",
max(DECODE(t.LN_ITEM, d.COLUMN_ITEM2, t.ITEM_AMT, 0)) keep (dense_rank first order by to_date(t.pay_prd,'yyyy-mm') desc ) "COL2",
max(DECODE(t.LN_ITEM, d.COLUMN_ITEM3, t.ITEM_AMT, 0)) keep (dense_rank first order by to_date(t.pay_prd,'yyyy-mm') desc ) "COL3",
max(DECODE(t.LN_ITEM, d.COLUMN_ITEM4, t.ITEM_AMT, 0)) keep (dense_rank first order by to_date(t.pay_prd,'yyyy-mm') desc ) "COL4",
max(t.PAY_PRD) PAY_PRD,
max(t.key1) keep (dense_rank first order by to_date(t.pay_prd,'yyyy-mm') desc ) key1,
max(t.key2) keep (dense_rank first order by to_date(t.pay_prd,'yyyy-mm') desc ) key2
from MY_PAY_ITEMS t
join MY_ITEM_DISPLAY d
on d.display_code = '01'
where t.emp = '00000011'
group by d.display_code, t.emp, d.sequence
) q
full outer join (select level*10 s from dual connect by level <= 4) m
on m.s = q.sequence
DISPLAY_CODE
EMP
S
COL1
COL2
COL3
COL4
PAY_PRD
KEY1
KEY2
01
00000011
10
101.1
103.1
104.1
105.1
2010-03
008
005
01
00000011
20
107.1
113.1
104.1
109.1
2010-03
008
005
01
00000011
30
101.1
104.1
109.1
111.1
2010-03
008
005
01
00000011
40
0
0
0
0
2010-03
008
005
Ramin Hashimzade
Maybe you are looking for
-
Remote control and MCE remote on Windows
I am having issues with the remote control app on the Tablet S1 and MCE remotes on Windows 7 (64-bit). After learning the buttons for the MCE remote, pressing the same button more than once from the app does not do anything. For example, if I press t
-
I can't open the control centre with a Griffin Survivor Case on my iPhone 5.
The title says it all really. The plastic of the case ends really close to the screen and there is an inbuilt screen protector. This means I can't register touch on the bottom edge of the screen, which is apparently where you have to swipe to open th
-
Can't open my emails, can you help?
Can't open my emails, please help me
-
Setting "Aggregation For Plan" for Scenario members in Dimension Library
In the Dimension Library, I have a Scenario which has two members (B and C) which roll up to a parent member (A). Unlike the other types of dimensions, I am unable set the Aggregation as the properties (Aggregation for Plan 1, Aggregation for Plan 2,
-
Compression with zero elimination (reverse postings)
I executed a compression with zero elimination in a custom InfoCube in order to avoid entries that only contain zero values as key figures (for example reverse posting) are contained in the InfoCube after compressing. However, not all the entries whe