Outer Join Negation Question

I'm retrofitting an existing plsql report into BusinessObjects. I have a question about
the sql I'm looking at. There is an employee table and a case table. Employees have cases. There are two other tables...a case activity table and a case results table. There may or may not be activity and results for a given case. The query is this...
select count(distinct case_id)
employee.employee_id = case.employee_id
and case.case_id = case_activity.case_id (+)
and case.case_id = case_results.case_id (+)
so far so good. The next part is
and (case_activity.activity_date <= mm/dd/yyyy
or case_results.activity_date <= mm/dd/yyyy)
That cancels the outer join, right? I contend that there is no
reason for the outer join symbols. He says they're needed. He thinks the OR is making a difference. It looks to me like you've lost the guarantee that all cases will be included. Can someone please splain this to me :-)
Thanks so much!
Cindy

Cindy,
I hope there's not too much of an arguement brewing on that query, but both of you are correct (to a degree). The OR in that second clause makes all the difference. I have some sql to show some test results based on your query. Basically remeber this, you always get one row back when making a query, if ALL conditions are met you get that record back. So even if the first part of the OR failes and the second one is true then u get the row back.
Here's where that other fellow is having a problem though. The problem your going to have is when neither of thoes dates return ture then you get NO data back regardless of the outter joins. Thoes two table Activity and Results will become related if thought about like this. What I mean, is if there is a date in the Activity table that matches, then you will get the Result data as well, and vice-versa. However if there is neither Activity or Result date matches you loose the whole case record even though you have the outter join specified. UNLESS thats the whole point of that DATE range. If neither match then I dont want any case records back. I'm just assuming since your outter joining you want the case back the case regardless if there are matches or not in Activity and Results, but maybe this isn't so.
Anyway, here some SQL for you and the data that produced it ...
Tables (t1,t2,t3,t4) : t1is employee, t2 is case t3 is activity and t4 is result.
Columns (c1,n1,d1) : varchar ID , number ID and a date
All dates are set for today (Arpil 5, 2002)
Data is the same in ALL the tables, only interested in C1= A and N1 = 1 from main table T1
Table T1 has 1 record where C1= 'A' and N1= 1
SQL> select c1,n1,d1 from t1 where c1='A' and n1=1;
C1 N1 D1
A 1 05-APR-02
Case #1 (BOTH t3 and t4 have no matches)
SQL> select DISTINCT
2 t1.c1 "t1_c1",t1.n1 "t1_n1",
3 t2.c1 "t2_c1",t2.d1 "t2_d1",t2.n1 "t2_n1",
4 t3.c1 "t3_c1",t3.d1 "t3_d1",t3.n1 "t3_n1",
5 t4.c1 "t4_c1",t4.d1 "t4_d1",t4.n1 "t4_n1"
6 from t1,t2,t3,t4
7 where
8 (
9 t1.C1 = t2.C1 and
10 t2.c1 = t3.c1 (+) and
11 t2.c1 = t4.c1 (+) and
12 (T3.D1 <= to_date('2002/04/04','yyyy/mm/dd') or T4.D1 <= to_date('2002/04/04','yyyy/mm/dd'))
13 )
14 ;
no rows selected
This SQL produces no data as BOTH dates in t3 (Activity) and t4 (Results) have no matches since all D1 are set to today. Even though there is an outter join the whole [ ( date match t3 OR date match t4 ) ] fails so no records (or cases) get produced).
The below Case #2 I changed the columns selected to a COUNT since this query would produce too much data to make of any sence in there. Besides, and I hope you oracle folks read this, the FONT makes any kind of query output impossible read. Ahhhhh I'm making something better at the moment for the public anyway.
SQL> select DISTINCT
2 count(t1.c1),count(t2.c1),count(t3.c1),count(t4.c1)
3 from t1,t2,t3,t4
4 where
5 (
6 t1.C1 = t2.C1 and
7 t2.c1 = t3.c1 (+) and
8 t2.c1 = t4.c1 (+) and
9 (T3.D1 <= to_date('2002/04/04','yyyy/mm/dd') or T4.D1 <= to_date('2002/04/04','yyyy/mm/dd'))
10 )
11 AND t1.c1 ='A' AND T1.N1 = 1;
COUNT(T1.C1) COUNT(T2.C1) COUNT(T3.C1) COUNT(T4.C1)
0 0 0 0
So as you can see with BOTH dates not having any matches you get no data back at all even with the outer joins. So yes in this case it does not matter if your outer joinning or not, the whole date clause falied and since it id ANDed to the whole where clause , the whole where clause fails and you get no data.
Case #2 (table t3 has a date match but non in t4) : Only change to SQL was change the DAY from 04 to 05 ;being today). Bascially you get ALL the data from t1,t2,t3 AND t4. The record entries in T4 still show up even though there are no matches and the data from t4 shows up, it is not null.
SQL> select DISTINCT
2 count(t1.c1),count(t2.c1),count(t3.c1),count(t4.c1)
3 from t1,t2,t3,t4
4 where
5 (
6 t1.C1 = t2.C1 and
7 t2.c1 = t3.c1 (+) and
8 t2.c1 = t4.c1 (+) and
9 (T3.D1 <= to_date('2002/04/05','yyyy/mm/dd') or T4.D1 <= to_date('2002/04/04','yyyy/mm/dd'))
10 )
11 AND t1.c1 ='A' AND T1.N1 = 1;
COUNT(T1.C1) COUNT(T2.C1) COUNT(T3.C1) COUNT(T4.C1)
8 8 8 8
And no I didn't just chage the count numbers to 8. Notice though you still get t4 matches since the ID join is true, even though the dates are not. If you only wanted T3 records out then you would have to split out the t3 date and the t4 date from that OR clause. The same results occur if T4 has date mathces and T3 does not. Same result if BOTH have matches in t3 and t4.
Case #3 : both t3 and t4 have no matches on date (both are set to yesterday, same as case #1) but you will want the data returned. Since the ID exists in both t3 and t4, but the dates do not, by adding another OR clause your OUTER joins will work ...
SQL> select DISTINCT
2 count(t1.c1),count(t2.c1),count(t3.c1),count(t4.c1)
3 from t1,t2,t3,t4
4 where
5 (
6 t1.C1 = t2.C1 and
7 t2.c1 = t3.c1 (+) and
8 t2.c1 = t4.c1 (+) and
9 (T3.D1 <= to_date('2002/04/04','yyyy/mm/dd') or T4.D1 <= to_date('2002/04/04','yyyy/mm/dd'))
10 )
11 OR
12 (
13 t1.C1 = t2.C1 and
14 t2.c1 = t3.c1 (+) and
15 t2.c1 = t4.c1 (+)
16 )
17 AND t1.c1 ='A' AND T1.N1 = 1;
COUNT(T1.C1) COUNT(T2.C1) COUNT(T3.C1) COUNT(T4.C1)
8 8 8 8
You can try this your self if you like, but overall if any part of and AND clause failes, no matter if part of it had 100 OR clauses in one set of brackets, it all fails, even if you have outer joins.
Have a kick butt weekend and good luck with your sql, email if you need anything :)
Tyler
[email protected]

Similar Messages

  • Question on using the outer join

    SELECT
    SIAP.FLIGHT_PROCEDURE.PROC_CNTL_NUMBER,
    SIAP.FLIGHT_PROCEDURE.PROCEDURE_NAME,
    SIAP.FLIGHT_PROCEDURE.AMENDMENT_NUMBER,
    FLOOR (flight_procedure.amendment_number),
    CHR ( ( flight_procedure.amendment_number
    - FLOOR (flight_procedure.amendment_number))
    * 100
    SIAP.FLIGHT_PROCEDURE.FACILITY_IDENT,
    SIAP.PROC_AIRPORT.AIR_ID,
    SIAP.PROC_AIRPORT.NAME,
    SIAP.PROC_AIRPORT.LOCATION,
    SIAP.PROC_AIRPORT.STATE_CODE,
    SIAP.PROC_AIRPORT.COUNTRY_CODE,
    SIAP.FLIGHT_PROCEDURE.EFFECTIVE_START_DATE,
    SIAP.FLIGHT_PROCEDURE.STATUS_IND,
    APTS.APTS_TASK.TASK_DESCRIPTION,
    APTS.APTS_TASK.IFP_CNTRL_NO,
    APTS.APTS_TASK.IFP_RCNTRL_NO,
    APTS.APTS_TASK.IFP_CNTRL_REF,
    APTS.APTS_TASK.IFP_RCNTRL_REF
    FROM
    APTS.APTS_TASK,
    SIAP.PROC_AIRPORT,
    SIAP.FLIGHT_PROCEDURE
    WHERE
    ( SIAP.FLIGHT_PROCEDURE.PROC_CNTL_NUMBER=SIAP.PROC_AIRPORT.PROC_CNTL_NUMBER )
    AND ( SIAP.FLIGHT_PROCEDURE.AMENDMENT_NUMBER=SIAP.PROC_AIRPORT.AMENDMENT_NUMBER )
    AND APTS.APTS_TASK.IFP_CNTRL_NO = TO_CHAR (flight_procedure.proc_cntl_number)(+)
    AND APTS.APTS_TASK.IFP_RCNTRL_NO = flight_procedure.amendment_number(+)
    I want to get all the records from APTS_TASK table even if they do not exist in SIAP.FLIGHT_PROCEDURE. So I have created a outer join APTS_TASK table and flight_procedure table to get all the records from APTS. I get all the records if I use just the two tables APTS_TASK and FLIGHT_PROCEDURE. But when I include SIAP.PROC_AIRPORT in the query I loose some records from the query. So If I want to get all the records should I include all the outer join to SIAP. PROC_AIRPORT table too. I tried to make this clear but let me know if you have more questions.

    SELECT
    SIAP.FLIGHT_PROCEDURE.PROC_CNTL_NUMBER,
    SIAP.FLIGHT_PROCEDURE.PROCEDURE_NAME,
    SIAP.FLIGHT_PROCEDURE.AMENDMENT_NUMBER,
    FLOOR (flight_procedure.amendment_number),
    CHR ( ( flight_procedure.amendment_number
    - FLOOR (flight_procedure.amendment_number))
    * 100
    SIAP.FLIGHT_PROCEDURE.FACILITY_IDENT,
    SIAP.PROC_AIRPORT.AIR_ID,
    SIAP.PROC_AIRPORT.NAME,
    SIAP.PROC_AIRPORT.LOCATION,
    SIAP.PROC_AIRPORT.STATE_CODE,
    SIAP.PROC_AIRPORT.COUNTRY_CODE,
    SIAP.FLIGHT_PROCEDURE.EFFECTIVE_START_DATE,
    SIAP.FLIGHT_PROCEDURE.STATUS_IND,
    APTS.APTS_TASK.TASK_DESCRIPTION,
    APTS.APTS_TASK.IFP_CNTRL_NO,
    APTS.APTS_TASK.IFP_RCNTRL_NO,
    APTS.APTS_TASK.IFP_CNTRL_REF,
    APTS.APTS_TASK.IFP_RCNTRL_REF
    FROM
    APTS.APTS_TASK,
    SIAP.PROC_AIRPORT,
    SIAP.FLIGHT_PROCEDURE
    WHERE
    ( SIAP.FLIGHT_PROCEDURE.PROC_CNTL_NUMBER=SIAP.PROC_AIRPORT.PROC_CNTL_NUMBER )
    AND ( SIAP.FLIGHT_PROCEDURE.AMENDMENT_NUMBER=SIAP.PROC_AIRPORT.AMENDMENT_NUMBER )
    AND APTS.APTS_TASK.IFP_CNTRL_NO = TO_CHAR (flight_procedure.proc_cntl_number)(+)
    AND APTS.APTS_TASK.IFP_RCNTRL_NO = flight_procedure.amendment_number(+)
    AND SIAP.PROC_AIRPORT.PROC_CNTL_NUMBER = AIRPORT.PROC_CNTL_NUMBER
    AND SIAP.PROC_AIRPORT.REVISION NUMBER=AIRPORT.REVISION NUMBERIf I add the airport table also to the join like shown above,should I also do the cascading join to the proc_airport.

  • Query Question: Combine outer join with max() statement

    Hi Folks,
    I have been banging my head on this for a while now and am asking from some advice.
    I have a Project Completion Report that pulls information from a number of tables:
    1) Program (PK: ID)
    2) Project (PK: ID, FK: Program_ID constrained to Program.ID)
    3) Project_Monthly (PK: ID, FK: Project_ID constrained to Project.ID)
    4) Status_Report (PK: ID, FK: Project_ID constrained to Project.ID)
    The Status_Report table has a Record_Date field and holds a BLOB with the status reports for all the projects. In the best of all possible worlds, every project would have a status report, but, obviously, some have no status reports.
    I have been asked to extend the Project Completion Report. It currently shows:
    1) Program Number (Program.Program_Number)
    2) Program Name (Program.Program_Name)
    3) Project (Project.Project_Name)
    4) Projected Completion Date (Project_Monthly.Current_Date_Production)
    We would like to add the latest status report. So I started with something that works in another report, which is to get the ID from the Status_Report table for the record that has the maximum date value in the Record_date that matches the Project in the current Program. But this other query is looking at one program at a time. The Project Completion Report is showing all programs with projects that complete within a certain time frame.
    The requirement is to show all projects that will complete within a time frame and to display the ID of the most recent status report (I use javascript to turn this into a downloadable link). However, whenever I try something like:
    AND Status_Report.Record_Date =
    (select MAX(Status_Report.record_date) from Status_Report
    where Status_Report.ID = Project.ID)I loose all projects that have no status reports associated with them.
    How can I keep all the projects that fulfill the criteria of completing within a specified time frame and add the ID, if it exists, of the most recent status report?
    I thank you for your time and assistance. Please let me know how I can clarify the problem more clearly.
    Yours,
    Petie

    I had thought I finally solved it. Alas, it wasn't yet to be.
    I created a view with the following select statement:
    select p.program_number, p.program_name,
    pj.id as pj_id, pj.project_name, pjm.in_prod_current, pjm.record_date as pjm_record_date,
    prs.id as prs_ID, prs.record_date as prs_record_date
    from program p, project pj, project_monthly pjm,
    project_status_report prs
    where p.id = pj.program_id
    and pj.id = pjm.project_id
    and pj.id = prs.project_id (+);Then, I selected from the view and the project_status_report table, performed an outer join on those (filtered to only the current month's project records) and filtered by the maximum date for each project.
    Here is the resulting query:
    select pc.program_number, pc.pj_id, pc.project_name, pc.in_prod_current,
    pc.pjm_record_date, pc.prs_id
    from project_completion pc,
    project_status_report prs
    where trunc(pjm_record_date, 'mon') = trunc(sysdate,'mon')
    and prs.id = pc.prs_id (+)
    and pc.prs_record_date =
    (select max(mprs.record_date)
    from project_status_report mprs
    where mprs.project_id = pc.pj_id)However, I am still not getting the projects for which there are no status reports.
    Verflixt und zugenaeht!
    It seems that I want to compare based upon the record_date of the status report, but get the ID back. Can I use DECODE for that? Can I get the MAX(prs.record_date), but return only the prs.ID? Because if I include the ID in the select statement, I get too many matches, but if I don't then I don't have the ID, which is needed.
    Any suggestions?
    Thanks, Petie
    Message was edited by:
    Petie

  • OBIEE not applying outer join syntax to filters

    (Note: I've already thoroughly searched the forums before posting this. Thanks)
    My problem is the following:
    I'm trying to build a report that is a count from my fact table, grouped by month from my date dimension for a given year, resulting in 12 data points. The problem is that not all months have actual data, but I still need those months to show on the report with a count of zero. Typical simple reporting requirement.
    I have already done the obvious and within my business layer made the join between my fact table and my date dimension an outer join on the fact side, just like you'd do if writing the query by hand. And when tested by hand this includes all dates for the year anyway, and when coupled with the appropriate null test on the count measure I'd get my 12 data points with zeros were appropriate.
    The problem is that there are additional filters I need to apply on the fact data (there are a couple text-based code values that didn't warrant full tables themselves so are just degenerate dimensions directly on the fact table.)
    When these filters are applied at the Answer level, I'm only getting back the months that actually have data, and lose the months where the count should be zero. A check of the session log for the query that was generated shows the problem. While OBI properly generates the outer-join syntax for the join itself between the two tables (my date dim and fact table) it does NOT apply the outer-syntax to the constant-based filter against the fact, effectively negating the outer join.
    Actual query from the log (I simply changed the table aliases from the ugly T##### stuff OBI generates to something more readable for posting here):
    select D.DT_MONTH_NAME as c1,
    D.DT_MONTH_NUM as c2,
    I.INC_TYPE as c3,
    I.INC_EMP_GROUP as c4,
    sum(case when I.INC_KEY is null then 0 else 1 end ) as c5
    from DATE_DIM D, INCIDENT_F I
    where ( D.DATE_KEY = I.DATE_KEY (+) ) and ( D.DT_YEAR = 2010 and I.INC_EMP_GROUP = 'CONTRACTOR' )
    group by D.DT_MONTH_NUM, D.DT_MONTH_NAME, I.INC_TYPE, I.INC_EMP_GROUP
    order by c2
    You can see that the outer syntax (+) is applied to the join, but not to the filter on I.INC_EMP_GROUP. If I take this query and drop it in something like SQL Developer, it only returns the months with data. If I throw the (+) after I.INC_EMP_GROUP like I'd do if writing this by hand, the desired zero-months results pop back in.
    I have already searched the forums and while lots of people seem to have asked this question, the only solutions involve things like trickery in the business layer using dummy fact tables followed by manipulations at the report level etc. Unfortunately I can't rely on these as the system is eventually to be turned over to users who can't be expected to apply various hacks to write reports.
    Anyone ever get to the bottom of getting OBI to apply outer join logic in filters as well, when the filtered table is meant to be outer-joined to?
    Any comments are appreciated.
    John

    I know that this thread is a bit old thought it might be helpful to some one...
    The Issue is, when using Degener@teDimen$ion ( this is !nner joned to FACT tables in BMM) and if any of the dimensions {other than theDegener@teDimen$ion (Let us say Dim X) } have an ()uter join to any of the fact tables, and you were doing your analysis using Degener@teDimen$ion,  Dim X, Measure value you will face the following issues.
    when filtering the analysis on the ()uter join dimension ( Dim X), the IN filter will not work. Reason is that the filter is getting applied to both the Dimension and FACT tables and the values that exist in Dimension Dim X but not in FACT table wont show up.
         The above issue can be fixed by changing the join between the fact and Degener@teDimen$ion from inner to outer. I think this is a bug.. because  it is supposed to filter the fact  table after the entire outer joined result is obtained but not filter the fact table for the Dim X values and do a outer join. I think the BI should be intelligent enough.

  • Outer Join logic

    The following code is an example of how to perform an outer join, in this case with ReportQuery (thanks Doug):
            ExpressionBuilder eb = new ExpressionBuilder();
            ReportQuery rq = new ReportQuery(Employee.class, eb);
            rq.addAttribute("firstName");
            rq.addAttribute("lastName");
            rq.addAttribute("areaCode", eb.anyOfAllowingNone("phoneNumbers").get("areaCode"));
            List<ReportQueryResult> results =  (List<ReportQueryResult>) session.executeQuery(rq);My question is about the logic Toplink uses to generate the outer join statement with the "(+)" in the generated sql.
    Does Toplink only generate the join statement if the same attribute is chosen in the select statement (in the above example "areaCode")?
    Along the same line of questioning, does it matter which attribute was in the get() call? So, in the above example did it have to be areaCode, or could it have been any other attribute of phoneNumber, and it still would have performed the join?
    In my case, because the selection attributes are built up dynamicly, should I add all attributes of my child class (my equivalent PhoneNumber class)?

    Thanks for your reply Doug.
    One last question, hopefully.
    I have a parent table with 2 child tables. When attempting an outer join with both, toplink does not attempt to outer join either. I understand why, sort of - as you get an error when attempting this in sqlplus with "(+)" syntax.
    I understand that you can outer join > 1 other table to a parent with ansi sql syntax:
        select dept.*,emp.*
        from dept left outer join emp
        on dept.deptno = emp.deptnoWill toplink allow > 1 child table outer join to a parent table?

  • FULL OUTER JOIN In InfoSet

    Hi, all
    Is it possible to make FULL OUTER JOIN in BI InfoSet?
    If no, another question - is it possible to switch base InfoProvider? I have an InfoSet with InfoCube1 and DSO1 which I can outer join. I want to outer join InfoCube1 , not DSO1 that's why I need to switch them in the InfoSet.

    Hi,
       In BI 7.0 Infoset has given chance to include an Info cube also,maximum you can include 2 info Cubes only in a infoset.
    check the below link which helps you in understanding of the join conditions so that you can apply to your scenario.
    http://help.sap.com/saphelp_nw2004s/helpdata/en/f1/713c3b35703079e10000000a114084/content.htm
    http://help.sap.com/saphelp_nw2004s/helpdata/en/67/7e4b3eaf72561ee10000000a114084/content.htm
    Regards,
    Praveena.

  • Problem with outer join

    Tables
    Normal EMP TABLE and dept TABLE
    query
    SELECT e.deptno,d.dname
    FROM emp e , dept d
    WHERE E.DEPTNO(+)=D.DEPTNO
    AND (e.deptno=20 or e.job='CLERK')
    question
    When i use the above query i cannot get the extra records from dept table( 40 , OPERATIONS) due to a condition
    as long as it is "OR" we cannot use outer joins.
    Regardless of that condition i need to get that record(40,OPERATION)
    Please reply me it is very urgent for my work now..
    regards
    Boopathi

    select e.deptno,d.dname
    FROM emp e , dept d
    WHERE E.DEPTNO(+)=D.DEPTNO
    AND (e.deptno=20 or e.job='CLERK')
    This will only fetch the record for 20, IF you want for deptno 40 then you should remove your AND clause (AND (e.deptno=20 or e.job='CLERK'))
    select * from dept
    ===========
    DNAME     DEPTNO
    OPERATION     20
    FINANCE     40
    TRADE     22
    select * from emp
    ===========
    ENAME     DEPTNO     JOB
    a     20     CLERK
    b     22     XXX
    select e.deptno,d.dname
    FROM emp e , dept d
    WHERE e.DEPTNO(+)=d.DEPTNO
    =======================
    DEPTNO     DNAME
    20     OPERATION
    22     TRADE
         FINANCE--- This is the one which does not ahve a record in emp but is there in dept hence it has been returned

  • Issues with limit/filter on outer join table in BQY

    I'm converting a series of BQY's from Brio 6.6 to Hyperion 9.3. I have some questions about the "use ODBC outer join syntax on limits" option in the OCE. I sort of understand this option's purpose, but I don't completely understand the SQL I'm seeing. For example Brio 6.6 is generating the following SQL statement:
    SELECT * FROM tblA AL1 LEFT OUTER JOIN tblB AL38 ON (AL38.ParentID=AL1.ChildID AND
    AL38.Data='SomeData') WHERE ((NOT AL38.Action IS NULL))
    Now, Hyperion 9.3 generated the SQL statement as follows:
    SELECT * FROM tblA AL1 LEFT OUTER JOIN tblB AL38 ON (AL38.ParentID=AL1.ChildID AND
    AL38.Data='SomeData') AND (NOT AL38.Response IS NULL))
    My questions are:
    1) Why isn't the "NOT AL38.Action IS NULL" statement included in the outer join in Brio? My limited understanding of the "use ODBC outer join syntax on limits" seems to indicate that it should end up there. I want the SQL to look like this, but I don't know why Brio generates this SQL.
    2) How can I get Hyperion to generate the same SQL as Brio? And still use the OCE with "use ODBC outer join syntax on limits" selected?

    Setting the Cardinality of Department > Employee role to OptionalOne
    gives rise to cartesian join (which is a bigger issue).
    Therefore, the Cardinality of Department > Employee role should remain as
    OptionalMany (default).
    This means, the outer join problem still remains unsolved. I have, therefore,
    unmarked the above answer by me.
    The question is - why has Report Builder been designed in such a way that the primary entity is always the child entity when attributes are selected from both parent and child entities?
    Most people desire that all the rows of the parent entity be fetched irrespective of whether there are corresponding rows in the child entity or not. Report Builder tool should not dictate what the user wants to get, meaning it is not right to assume
    that the focus of the report is Employee when attributes are selected from both Department and Employee. Report Builder should not make the child entity (i.e., Employee) as the primary entity when the user selects attributes from the child entity after
    having selected attributes from the parent entity.
    I am sorry to say that clients may not accept the Report Builder tool as this does not fetch the records as desired.
    I hope there is someone who can suggest how the outer join problem can be solved by just tweaking the properties of the report model (SMDL).
    Besides, the end users are business users and are not tech savvy. They are not expected to modify queries. They would simply drag and drop attributes from entities to create adhoc reports.

  • 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

  • How to use outer join condition in my below query.

    Hi All,
    How to use outer join condition in my below query.
    In the table  APPS_JP.GEDIS_OFFER_HEADER goh I have more records
    in the table APPS_JP.GEDIS_ORDER_BUILDS gob I have less number of records.
    I want all the records from APPS_JP.GEDIS_OFFER_HEADER goh
    including other conditions.
    I have tried goh.OFFER_NO=gob.OFFER_NO(+) but same result.
    [code]SELECT   GOH.ORIG_SYSTEM,
               gsp.USER_NAME,
               goh.ORDER_NO,
               goh.OMEGA_ORDER_NUMBER,
               goh.ORDER_TYPE,
               gc.CUSTOMER_ID,
               gc.OMEGA_CUSTOMER_NUMBER,
               CASE WHEN gc.PRIVATE = 'N' THEN gc.CUSTOMER_NAME ELSE '' END
                  AS COMPANY_NAME,
               goh.ORDER_STATUS,
               goh.TOTAL_SELLING_PRICE,
               goh.TOTAL_MARGIN,
                  ga1.ADDRESS1
               || ','
               || ga1.ADDRESS2
               || ','
               || ga1.ADDRESS3
               || ','
               || ga1.POSTAL_CODE
               || ','
               || ga1.CITY
                  AS SHIPPING_ADDRESS,
                  ga2.ADDRESS1
               || ','
               || ga2.ADDRESS2
               || ','
               || ga2.ADDRESS3
               || ','
               || ga2.POSTAL_CODE
               || ','
               || ga2.CITY
                  AS BILLING_ADDRESS,
               ga.ADDRESS_ID,
               gol.DESCRIPTION,
               APPS_JP.TZ.to_local_date (goh.OFFER_DATE, goh.OFFER_DATE_UTC)
                  AS OFFER_DATE,
               gc.LEVEL_8,
               goh.NO_OF_BUILDS,
               gob.SFDC_ID,
               goh.PURCHASE_ORDER_NO AS PO,
               gc1.CUSTOMER_NAME AS END_USAGE,
               gol.LOB,
               goh.TOTAL_MARGIN_PCT,
               goh.TOTAL_DISCOUNT,
               goh.TOTAL_DISCOUNT_PCT
        FROM   APPS_JP.GEDIS_OFFER_HEADER goh,
               APPS_JP.GEDIS_ORDER_BUILDS gob,
               APPS_JP.GEDIS_ORDER_LINES gol,
               APPS_JP.GEDIS_OFFER_RELATED_CUSTOMER gorc,
               APPS_JP.GEDIS_OFFER_RELATED_CUSTOMER ship,
               APPS_JP.GEDIS_OFFER_RELATED_CUSTOMER bill,
               APPS_JP.GEDIS_CUSTOMER gc,
               APPS_JP.GEDIS_CUSTOMER gc1,
               APPS_JP.GEDIS_CONTACT gct,
               APPS_JP.GEDIS_ADDRESS ga,
               APPS_JP.GEDIS_ADDRESS_NORM ga1,
               APPS_JP.GEDIS_ADDRESS_NORM ga2,
               (SELECT   DISTINCT SALESPERSON_ID, USER_NAME
                  FROM   APPS_JP.GEDIS_SALESPERSON
                 WHERE   SALESPERSON_ID IN
                               (SELECT   TO_NUMBER (COLUMN_VALUE) AS SALESPERSON_ID
                                  FROM   TABLE (APPS_GLOBAL.SplitString ('337309'))))
               gsp
       WHERE       goh.ORDER_NO <> 0
               AND goh.OFFER_NO <> 0
               AND goh.OFFER_NO=gol.OFFER_NO
               AND gol.BUILD_NO = 1
               AND gol.LINE_NO = 1
               AND goh.OFFER_NO=gob.OFFER_NO
               AND gob.BUILD_NO = 1
               AND goh.OFFER_NO = gorc.OFFER_NO
               AND gct.CONTACT_ID = gorc.CONTACT_ID
               AND ga.CUSTOMER_ID = gc.CUSTOMER_ID
               AND ga.PRIMARY = 'Y'
               AND goh.LEAD_SALESPERSON=gsp.SALESPERSON_ID
               AND goh.OFFER_NO = ship.OFFER_NO
               AND ship.RELATION_TYPE = 'SHIP'
               AND ga1.ADDRESS_ID = ship.ADDRESS_ID
               AND ga1.CUSTOMER_ID = gc1.CUSTOMER_ID
               AND goh.OFFER_NO = bill.OFFER_NO
               AND bill.RELATION_TYPE = 'BILL'
               AND ga2.ADDRESS_ID = bill.ADDRESS_ID
               AND goh.OFFER_DATE BETWEEN APPS_JP.TZ.LOCAL_TO_DB_DATE (
                                             SYSDATE - 30
                                      AND  APPS_JP.TZ.LOCAL_TO_DB_DATE (SYSDATE)
               AND gorc.RELATION_TYPE = 'BASE'
               AND gorc.CUSTOMER_ID = gc.CUSTOMER_ID
               AND goh.SALES_CHANNEL = gc.SALES_CHANNEL
               AND gc.SALES_CHANNEL = 'SMB'
               AND goh.LEAD_SALESPERSON IN (goh.CREATED_BY, goh.LEAD_SALESPERSON)
    ORDER BY   goh.OFFER_NO;[/code]
    Please help me how to use this outer join condition.
    Thanks in advance.

    Hi,
    If you want all the rows from goh, then you don't want any conditions like  goh.OFFER_NO <> 0.
    Make all the joins to goh outer joins, and make all conditions that apply to any tables joined to goh (or to tables joined to them) part of the join condition, like this:
    FROM             APPS_JP.GEDIS_OFFER_HEADER     goh
    LEFT OUTER JOIN  APPS_JP.GEDIS_ORDER_BUILDS     gob  ON   gob.OFFER_NO = goh.OFFER_NO
                                                         AND  gob.BUILD_NO = 1
    LEFT OUTER JOIN  APPS_JP.GEDIS_ORDER_LINES      gol  ON   gol.OFFER_NO = goh.OFFER_NO
                                                         AND  gol.BUILD_NO = 1
                                                         AND  gol.LINE_NO  = 1
    LEFT OUTER JOIN  APPS_JP.GEDIS_OFFER_RELATED_CUSTOMER
                                                    gorc ...
    I hope this answers your question.
    If not, post a little sample data (CREATE TABLE and INSERT statements, relevant columns only) for all the tables involved, and the results you want from that data.
    Simplify the problem as much as possible.  For example, do you really need all those tables to show what the problem is?  Of course, you need them in tyour real query, but if you understand a solution that only involves 4 or 5 tables, you'll know how to apply it to any number of tables.
    Explain, using specific examples, how you get those results from that data.Always say what version of Oracle you're using (e.g. 11.2.0.2.0).
    See the forum FAQ https://forums.oracle.com/message/9362002#9362002

  • How can we make consecutive left outer joins in Composite Provider?

    Hi,
    For the following design:
    Sales order and Delivery DSO's are unions on field Delivery Number.
    Invoice(Billing DSO) is having left outer join and joins with Sales Order DSO's based on the field Sales Order Number.
    Shipment DSO has left outer join, joins with Invoice DSO based on Delivery number.
    My doubt here in this composite provider design, is more than one consecutive left outer joins(in Invoice, shipment dso join) are allowed?
    Since this is possible in SAP ERP through writing abap codes, I came across that this kind of modelling is not possible in BW on  Hana through Composite provide kindly suggest how can we achieve this design in SAP BW On hana.
    Regards,
    Antony Jerald.

    Hi,
    Could anyone please help me on this?
    Hope, you are able to understand my question.  Please suggest.
    Regards,
    Antony Jerald.

  • Multiple Outer join in ORACLE 8.1.6

    Hi ,
    Can anybody suggest me how can i use multiple outer join on one table. I'm using ORACLE 8.1.6.
    I know this version of oracle doesnt support this. But is there anmy other wa\y I can achieve this.
    Thanks amd Regards
    Deependra

    Tricky question - but I went through this about 3 months ago, and found a good thread on here that explains it pretty well.
    check out Re: Outer join a table with two diff table
    You basically will have to create an inline view with one outer join in there, and then a second outer join on the outside. Read through the posts in that thread and it should help!

  • Help requried with outer joins

    Hi All,
    I neeed a query help can any one please help me getting this done,
    for the below query
    select trunc(assumed_time_sql) AS date1,sum(rp.rebate_due)as sum1 from mn_date_dim dd ,mn_rebate_payment rp,mn_prc_program prc,mn_structured_doc sd
    where trunc(assumed_time_sql) in (TO_DATE('01-JUL-10','dd-mon-yy'),add_months(TO_DATE('01-JUL-10','dd-mon-yy'),-3),add_months(TO_DATE('01-JUL-10','dd-mon-yy'),-6),add_months(TO_DATE('01-JUL-10','dd-mon-yy'),-9))----input parameter
    AND trunc(dd.assumed_time_sql)=TRUNC(rp.start_date)
    AND prc.prc_program_id=rp.tiered_rebate_id
    AND sd.struct_doc_id=prc.struct_doc_id
    AND sd.struct_doc_id_num='M0000763'----input parameter
    group by trunc(assumed_time_sql);
    I am getting output as
    date1      sum1
    01-JAN-10      10
    01-APR-10     15
    01-JUL-10     20
    But i want my output to be as
    date1      sum1
    01-JAN-10      10
    01-APR-10     15
    01-JUL-10     20
    01-OCT-09 NULL
    I have tried with outer joins but this didn't help me
    Can any one please give me help in getting this done
    Thanks

    Hi,
    As SB pointed out, you'd better provide tables and data in order to be helped more efficiently.
    Anyway, you may want to investigate the use of NVL and/or DECODE so that you can translate NULL into valid values so they are returned to your select statement.
    HTH,
    Thierry
    Handle:  p78   
    Status Level:  Newbie (10) 
    Registered:  Mar 9, 2009 
    Total Posts:  60 
    Total Questions:  35 (30 unresolved)  Be kind to share your helpful / correct threads with other with marking them as ANSWERED
    Edited by: Urgent-IT on Feb 13, 2011 11:00 AM

  • Outer join query for SQL server from Oracle

    Hi All,
    My question is regarding making queries from Oracle to SQL Server database thorugh DBLink.
    In my oracle database I have a DBLink emp.world for SQL Server database.
    I need to query SQL Server data from oracle (so that this query can be combined with other oracle tables).
    Query is given below:
    SELECT
            a."EmpID" as "Employee ID",
            a."EmpStatus" "Employee Status"
            b."EmpSub" as "Employee Subjects"
    FROM
            [email protected] a
            left outer join [email protected] b on a."EmpID" = b."suEmpID"
    ORDER BY  a."EmpID";My problem is when I run the same query from oracle, it does not show the EmpID that does not exist in Subjects table, but when run from actual SQL Server database, it shows all the records.
    Samples are given below:
    Run from Oracle
    Employee ID      Employee Status     Employee Subjects
    101                     Active                     Maths
    102                     Active                     Maths
    102                     Active                     Physics
    104                   Inactive                  Chemistry
    Run form SQL Server
    Employee ID      Employee Status     Employee Subjects
    101                     Active                     Maths
    102                     Active                     Maths
    102                     Active                     Physics
    103                 Active                       NULL
    104             Inactive            ChemistryI am not sure why in oracle outer join for SQL server tables is not working. What is the right way for outer join in this case.
    I am using oracle database 10gR2 and SQL Server 2005.
    Please Help.
    Thanks.

    SELECT
    a."EmpID" as "Employee ID",
    a."EmpStatus" "Employee Status"
    b."EmpSub" as "Employee Subjects"
    FROM
    [email protected] a
    left outer join [email protected] b on a."EmpID" = b."suEmpID"
    ORDER BY a."EmpID";
    http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/queries006.htm#sthref3175
    From your description, it appears you may need a right outer join. You want to get back all the rows from 'B', not from 'A'. Try a right join and let us know.

  • Query with multiple outer joins

    I had a doubt with whether the following kind of query is valid with multiple outer-joins. The format of the query is something like this:-
    select A.col1, B.col2
    from table1 A, table2 B, table3 C where
    A.col3=B.col4(+) and B.col5=C.col6(+)
    This would mean the follwoing with regard to outer-joins in the query.
    1) fetch records with col3 in table A matching or not matching col4 in table B
    2) fetch records with col5 in table B matching or not matching col6 in table C
    So, this query is valid?
    I hope, my question is clear.
    Please, help in solving the doubt.
    regards

    This is valid and it works fine

Maybe you are looking for

  • Time Machine ERROR: Cannot complete FIRST back up

    Hello all. This is my sis's Mac mini, there was apparently a file or system corruption somewhere that it was not able to boot up, so send in for rescue and the tech was able to rescue all the users' data (sis & dad's) So Mac mini came home, I reforma

  • 24" 3.06GHz Ram question

    Hi there, I'm trying to upgrade my RAM without breaking the bank. I upgraded using Kingston Value RAM on my Macbook and it worked a treat. What I'm wondering is if I can use similar RAM for my new iMac? I've been looking at the specs and it appears t

  • Treo 700 wx battery

    My Treo 700 wx  will show a low battery warning & shut down, at various states of charge, even when charging. If I  unplug it, then remove the battery for a few seconds, then replace the battery, it will show full, half, or whatever charge it should

  • Prime 1.4 AVC Not displaying ms-lync

    Hello guys When browsing the AVC statistics on the WLC, I can see that ms-lync is among the top applications, however on the application dashboard of Prime 1.4, it is not in the list. There is alot of unclassified, and also some UndefinedXXXXXX categ

  • HT1933 Has anyone else had a problem with the app " Storage War$" it costs £1.99 and doesn't work???

    Hi I have been having a problem with an app I have purchased, it cost £1.99 and does not match the description This was a waste of time and I am outraged that Apple have not checked the game after it's reviews. However I want to get my money back as