Current Position:Home > Create a view that limits a large table, but also allows an outer join ?

Create a view that limits a large table, but also allows an outer join ?

Update:10-11Source: network consolidation
Advertisement
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.

The Best Answer

Advertisement
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
  • Create a view that limits a large table, but also allows an outer join ? Update:10-11

    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(1

  • How to create a view consisting of data from tables in2 different databases Update:10-11

    Using Oracle 10.2g I have 2 databases Gus and haggis on Comqdhb schema. glink indicates a databse link between Haggis and Gus In Gus there are tables student,subject,grade,school containing columns like upn... STUDENT upn academicYear SUBJECT subject

  • How to create a view on a Non-Transparent Tables. Update:10-11

    Hi, i want to create a view on P0001 & P0002 tables. these two tables are non transparent. Can any body help me , Thanks in Advance, Regards VinayHi Vinay It seems you program HR-ABAP. Generally it is not required to create views since we use LDB (Lo

  • Create opaque view in OBIEE with multiple tables Update:11-30

    Hi, I need some help with the opaque view since i have never created it in past. I want to create an opaque view which fetches data from multiple tables. Is it possible to do that ? Or is there any other alternate option available in OBIEE ? I read t

  • Create Materialized View  based on another database table using db link? Update:11-30

    SQL> SELECT sysdate 2 FROM [email protected] ; SYSDATE 21-NOV-12 SQL> CREATE MATERIALIZED VIEW USERCBR.V_T24_COUNTRY1 2 REFRESH COMPLETE 3 START WITH SYSDATE NEXT SYSDATE + (5/24) 4 AS 5 SELECT sysdate 6 FROM [email protected] ; CREATE MATERIALIZED VIEW USERC

  • Create a spatial index on a large table Update:10-11

    Hi all I think that I might be starting to push XE beyond what it is capable of, but I thought I would ask here to see if anyone has some ideas how to get around my problem. I have a table with around 8,000,000 record in it. It has position data in i

  • A DATA_BUFFER_EXCEEDED viewing data on a large table Update:11-30

    Hello, Am getting error below while fetching data in DS designer from SAP ECC Tables. Error calling RFC function to get table data: <RFC_ABAP_EXCEPTION-(Exception_Key: DATA_BUFFER_EXCEEDED, SY-MSGTY: E, SY-MSGID: I followed the KBA :  1752954 - DATA_

  • Questions about creating a foreign key on a large table Update:10-11

    Hello @ll, during a database update I lost a foreign key between two tables. The tables are called werteart and werteartarchiv_pt. Because of its size, werteartarchiv_pt is a partitioned table. The missing foreign key was a constraint on table wertea

  • Creating a view with a 2 same tables Update:11-30

    Hi experts. I have a Question... I want to make a view but I need to use the KNA1 table, but... I need again the KNA1 table to make a joing like this: KNA1_1.  and KNA1_2.KUNNR. But in the transaction se11, I don't know how can I make the alias for t

  • Can we create a view of a datasource and table? Update:11-30

    Hello all, I have to create an extractor, I want to get all the fileds from SAP delivered datasource, then add fields from table and 2 other fields. Can anyone suggest the best way of doing it? Thankshi Raj, what you mean from table and 2 other field