Set operator Vs Self join

hi all,
i have a main table and a corresponding history table.
Like employee and h_employee both has primary key as emp_id.
now i want a query which should only retrieve the common values among these two table.
I have an idea of doing this in two way 1.self join 2. set operator
1.select emp_id
from emp e,h_emp h
using (emp_id)
2. select emp_id from emp
intersect
select emp_id from h_emp
now guide me which gives better performance? how to evaluate the performance in PL/SQL Developer client?
is there any keyword to trace the timing of the each query?
Please advice.
Regards,
Slu

Set operators combines the output of 2 or more queries into single output....
Internally its doing sorting the two tables
Join is just matching the records based on the where condition ....
use Explain plan to the cost of the query
SQL> Explain plan for select emp_id
from emp e,h_emp h
using (emp_id)
and use
SQL > select * from plan_table
to see the cost...
Edited by: LPS on Jul 12, 2011 12:08 AM

Similar Messages

  • Set operations & tables with different columns

    I have a problem. I have 3 tables - Countries, Locations & Departments. I want to output the country_id and country_name from the countries tables for countries that have no departments. Locations has country_id and location_id columns and departments has location_id and department_id columns. All is in Database 11g. I can produce a table which gives me the locations with departments or without departments as follows:
    select location_id from locations intersect select location_id from departments;
    This gives me a list of locations with departments. Conversely I can get a list of locations without departments as follows:
    select location_id from locations minus select location_id from departments;
    However, to combine this output with the countries table I need to produce country_id in the output. However, when I try to add country_id to my code from above as follows:
    select country_id, location_id from locations intersect select to_char(null), location_id from departments;
    I get no rows found. I understand why. There is no intersection between country_id in locations and the null output from departments (where there is no country_id column). Alternatively, if I try as follow:
    select country_id, location_id from locations minus select to_char(null), location_id from departments;
    I get rows with every country_id whether they have departments or not. Again, I understand why. I am essentially subtracting nothing (the to_char(null) from departments) from the country_id column in locations and getting the entire country_id column as output.
    How can I use set operations to produce the country_id column? I also do not want to show the location_id problem.
    This problem is repeated when I try for the final country_id, country_name final output. The countries table has these columns. However, the locations table does not have the country_name column. It only has the country_id column. So a query such as this one:
    select country_id, country_name from countries intersect country_id, to_char(null) from locations;
    presents me with the same problem as above. The country_id column intersects nicely, but the country_name file does not intersect as it does not exist in the locations table. Again, how can I use set operations to produce the country_id and country_name columns.

    Hi,
    the method I outlined for you above should be fine. It doesn't matter that there are one-to-many relationships which may cause repeated output rows; set operations (except for UNION ALL ) always return distinct rows.
    Can you do a query on the countries table, that shows all countries?
    Can you do a query involving all 3 tables inner-joined, that shows the countries that are related to locations and departments? (Repeated rows are okay.)
    Then you can do a MINUS, to get only the countries that are not related to departments.
    If you get stuck, post a little sample data (CREATE TABLE and INSERT statements), the results you want from tha data, your best attemptat a query, and a description of the problem (including the full error message, if any).

  • Mapping - split followed by set operation

    Hi I'm trying to set up a mapping to use as part of testing my warehouse and need some help.
    Overview
    ======
    I have a number of different databases that combine through to my operational data store. One verification of our mappings is a simple check of record counts, source table vs target.
    Because table names differ between source and target I have loaded (from a flat file) a translation table that maps one table name to another.
    I have external SQL scripts that run on a scheduled basis to capture table names, record counts and date of last update from the system tables of four of my source databases and my target database. (soon I'll need to try and replace these with OWB scripts)
    I am trying to build a mapping to conform these so I end up with a single fact listing target table, record count, update date, source table, source environment, record count, update date.
    I have taken my statistics on the target database, outer Joined it to the translation table (not all target tables have matching translation table records)
    Then split the result set by target environment (and remainder)
    Then I join each result set to the statistics for the appropriate source.
    Next I am using a set operation to union all the results back to my conformed result.
    My Problem
    =========
    Those tables in the target database that do not correspond to a table in one of the four sources cause a problem. (they are either summary facts, flat files loaded or sourced from other databases I have not got statistics on yet)
    I can’t just link from the split’s output set to the set operation because the other joins have added extra fields for number of records in the source. The documentation is very clear that the same fields must exist in the same order and datatype.
    I have been trying to work out which mapping operation/s will produce the equivalent of SQL like “select col1, col2, null, sysdate, null from mytable”
    Hmm as I type this up I think another alternative may be to output extra fields in the split (so it looks like the dataset after the join) but not to pass these fields on in the join for sets for specific environments. I’ll try that alternative but would still like help with which mapping operator I could have used.

    Can I have a little bit more technical information : A small exmaple would be very helpful.
    Regards
    -Arnab

  • Oracle query with out using self join

    hi friends,
    i have one table for exeample PERSTATUS
    pk/fK STUDENT NUMBER SUBJECT MARKS STATUS
    1 ACCOUNTS 15 RED
    1 MATHS 35 YELLOW
    1 SCINECE 45 GREEN
    2 ACCOUNTS 55 BROWN
    2 MATHS 35 YELLOW
    2 SCINECE 45 GREEN
    3 ACCOUNTS 15 RED
    3 MATHS 35 YELLOW
    3 SCINECE 45 GREEN
    i want students how status is both red and yellow so i am using self join
    i want students status is both red and yellow so i am using self join
    SELECT PS.STUDENTNUMBER,PS.STATUS,PS.STATUS1 FROM PERSTATUS PS ,PERSTATUS PS1
    WHERE PS.STUDENTNUMBER-PS1.STUDENTNUMER
    PS.STATUS='RED' AND PS1.STAUTS='YELLOW'
    i want students status is both RD and YELLOW AND GREEN so i am using self join( two self joinS}
    SELECT PS.STUDENTNUMBER,PS.STATUS,PS.STATUS,PS2.STATUS FROM PERSTATUS PS ,PERSTATUS PS1,PERSTATUS PS2
    WHERE PS.STUDENTNUMBER-PS1.STUDENTNUMER AND PS.STUDENTNUMBER-PS2.STUDENTNUMBER
    PS.STATUS='RED' AND PS1.STAUTS='YELLOW' AND PS2.STAUTUS='GREEN'
    if i require MORE STATUS then more self joins required, is there any alternative to achive this
    and if results comes in multiple rows are accepted (since with the above query result will come in single row)
    i tried to use group by (studentnumber,status) with status='red' and status='yellow'
    but it is not possible could you povidet he solution

    Hi,
    Whenever you have a problem, please post CREATE TABLE and INSERT statements for your sample data, and the exact results you want from that data. Explain how you get those results from that data.
    See the forum FAQ {message:id=9360002}
    Here's an example of how to post the sample data:
    CREATE TABLE     perstatus
    (       studentnumber     NUMBER
    ,     subject          VARCHAR2 (10)
    ,     marks          NUMBER
    ,     status          VARCHAR2 (10)
    INSERT INTO perstatus (studentnumber, subject,    marks, status)
           VALUES           (1,           'ACCOUNTS', 15,       'RED');
    INSERT INTO perstatus (studentnumber, subject  ,  marks, status)
           VALUES           (1,           'MATHS',        35,       'YELLOW');
    INSERT INTO perstatus (studentnumber, subject,    marks, status)
           VALUES           (1,           'SCINECE',  45,       'GREEN');
    INSERT INTO perstatus (studentnumber, subject,    marks, status)
           VALUES           (2,           'ACCOUNTS', 55,       'BROWN');
    INSERT INTO perstatus (studentnumber, subject  ,  marks, status)
           VALUES           (2,           'MATHS',        35,       'YELLOW');
    INSERT INTO perstatus (studentnumber, subject,    marks, status)
           VALUES           (2,           'SCINECE',  45,       'GREEN');
    INSERT INTO perstatus (studentnumber, subject,    marks, status)
           VALUES           (3,           'ACCOUNTS', 15,       'RED');
    INSERT INTO perstatus (studentnumber, subject  ,  marks, status)
           VALUES           (3,           'MATHS',        35,       'YELLOW');
    INSERT INTO perstatus (studentnumber, subject,    marks, status)
           VALUES           (3,           'SCINECE',  45,       'GREEN');You were on the right track, thinking about GROUP BY. You're interested in something about the whole group of rows that has the same studentnumber. Looking at any individual row won't tell you if that row is part of the group you're interested in or not.
    If you want to see information about the group as a whole, you can do the whole job with GROUP BY. In this case, studnetnumber is the only thing that an entire group has in common. If you wanted to see the studentnumbers that had both RED and YELLOW, that is:
    STUDENTNUMBER
                1
                3here's one way you could do it:
    SELECT       studentnumber
    FROM       perstatus
    WHERE       status     IN ('RED', 'YELLOW')
    GROUP BY  studentnumber
    HAVING       COUNT (DISTINCT status) = 2  -- That is, both RED and YELLOW
    ORDER BY  studentnumber
    ;But say you wanted to see details about individuals in the group; for example, say we want to see all the columns for students that have all 3 of RED, YELLOW and GREEN, like this:
    STUDENTNUMBER SUBJECT         MARKS STATUS
                1 SCINECE            45 GREEN
                1 ACCOUNTS           15 RED
                1 MATHS              35 YELLOW
                3 SCINECE            45 GREEN
                3 ACCOUNTS           15 RED
                3 MATHS              35 YELLOWWe used the aggregate COUNT function earlier, but aggregate functions require collapsing the results down to one row per group.
    However, most of the aggregate functions, like COUNT, have analytic counterparts, that can give the same results without collapsing the result set. Here's one way to get the results above, using the analytic COUNT function:
    WITH     got_cnt          AS
         SELECT  studentnumber, subject, marks, status
         ,     COUNT ( DISTINCT CASE
                                   WHEN  status  IN ('RED', 'YELLOW', 'GREEN')
                             THEN  status
                               END
                    ) OVER (PARTITION BY  studentnumber)     AS cnt
         FROM    perstatus
    SELECT    studentnumber, subject, marks, status
    FROM       got_cnt
    WHERE       cnt  = 3
    ORDER BY  studentnumber
    ,            status
    ;

  • Oracle doc inconsistent on materialize view with union all and self joins

    First of all, I can't seem to create a materialized view containing self-joins AND union all. Is it possible?
    I checked Oracle 9i (my version: PL/SQL Release 9.2.0.4.0 - Production) documentation and I get different answers (or so it seems to me).
    First I saw this: "The COMPATIBILITY parameter must be set to 9.0 if the materialized aggregate view has inline views, outer joins, self joins or grouping sets and FAST REFRESH is specified during creation..."
    Did you see the part about 'self joins' in there? I did and I was pumped because that seems to say that you CAN have 'self joins' (and my compatibility is 9.2...)
    BUT
    In the very same document I also found "Oracle does not allow self-joins in materialized join views." (rage)
    You can see the document I am speaking of here: http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96520/mv.htm#574889
    Whenever I try to create the mview I get the following error. (
    In any caseORA-01446 cannot select ROWID from view with DISTINCT, GROUP BY, etc.

    First of all, I can't seem to create a materialized view containing self-joins AND union all. Is it possible?
    I checked Oracle 9i (my version: PL/SQL Release 9.2.0.4.0 - Production) documentation and I get different answers (or so it seems to me).
    First I saw this: "The COMPATIBILITY parameter must be set to 9.0 if the materialized aggregate view has inline views, outer joins, self joins or grouping sets and FAST REFRESH is specified during creation..."
    Did you see the part about 'self joins' in there? I did and I was pumped because that seems to say that you CAN have 'self joins' (and my compatibility is 9.2...)
    BUT
    In the very same document I also found "Oracle does not allow self-joins in materialized join views." (rage)
    You can see the document I am speaking of here: http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96520/mv.htm#574889
    Whenever I try to create the mview I get the following error. (
    In any caseORA-01446 cannot select ROWID from view with DISTINCT, GROUP BY, etc.

  • Set operations usecase

    hi,
    I am a new bee and would like to understand the use of SET operations ( UNION, UNIONALL, MINUS, INTERSECTION) can't we do the same with the use of JOINS ? Am I wrong ? please correct me....and few examples where there is no alternate except using SET operations will help me to understand the thing more clearly...
    Thanks and regards
    mahesh.

    Documentation at http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/queries004.htm#i2054381 might prove useful.

  • Need help with self join query

    Hello,
    I have table A with the following data
    oid parent_oid
    10 4
    4 2
    2 2
    12 6
    6 6
    parent_oid is the parent of oid. I'd like a query that shows the final parent of the oid. The result should show the following
    oid final parent
    10 2
    4 2
    2 2
    12 6
    6 6
    I'm using Oracle 10g. I'm familiar with self joins, but that alone will not do the job. Thanks!

    Hi,
    arizona9952 wrote:
    ... I'm familiar with self joins, but that alone will not do the job.You're absolutely right!
    A 2-way self join would work for rows have no parent, or rows that are directly connected to their final ancestor (such as oid=4), but not for anything farther away.
    A 3-way self-join would work for one more level away from the final row, but no more. That would be enough for the small set of sample data that you posted, but it would not work if you added a new row with parent_id=10.
    An N-way self-join would work for up to N+1 levels, but no more.
    You need something that can go any number of levels, such as CONNECT BY:
    SELECT     CONNECT_BY_ROOT oid     AS oid
    ,     parent_oid          AS final_parent
    FROM     a
    WHERE     CONNECT_BY_ISLEAF     = 1
    CONNECT BY     oid     = PRIOR parent_oid
         AND     oid     != parent_oid
    ;Edited by: Frank Kulash on Feb 22, 2010 7:09 PM
    Upon sober reflection, I think that a Top-Down query, like the one below, would be more efficient than a Bottom-Up query, like the one above:
    SELECT     oid
    ,     CONNECT_BY_ROOT     parent_oid     AS final_parent
    FROM     a
    START WITH     parent_oid     = oid
    CONNECT BY     parent_oid     = PRIOR oid
         AND     oid          != PRIOR oid
    ;

  • How to re-write this self join update using a CTE

    I would like to improve my performance on this update statement and would like to try re-writing using a CTE:
    UPDATE "usr_sessions" "a" SET "is_ended_at_trustable" = 't'
          WHERE (
            EXISTS (
              SELECT 1
              FROM "usr_sessions" "b"
              WHERE "a"."ended_at" = "b"."started_at"
                AND "a"."usr_space_id" = "b"."usr_space_id"
                AND "a"."account_id" = "b"."account_id"
          ) ) AND "a"."is_ended_at_trustable" IS NULL
    Any help is greatly appreciated!  Open to other suggestions as well if there is a better way!

    If I understood your description correctly, here's a way to accomplish the same thing, while dodging the need for the self join.   The update itself won't be any faster, but the overall query leading to the update will likely be faster sans self-join.
      (If my interpretation wasn't exactly what you meant, tweak the "partition by" clause).
    MERGE is generally considered better then UPDATE, but your particular update isn't at risk for the shortcomings of update (still, Merge is newer, cooler, and more trustworthy).
    Setup_Example_Data:
    Declare @Usr_Sessions table (account_id int, usr_space_id int, is_ended_at_Trustable Char(1), started_at varchar(99), ended_at varchar(99))
    Insert @Usr_Sessions
    Select 1, 10, 't', 'A1', 'A1'
    UNION ALL Select 2, 20, 'f', 'B1', 'B2'
    UNION ALL Select 3, 30, NULL, 'C1', 'C1'
    UNION ALL Select 4, 40, NULL, 'D1', 'D2'
    UNION ALL Select 5, 50, NULL, 'E1', 'E2'
    UNION ALL Select 5, 51, NULL, 'E3', 'E3'
    UNION ALL Select 6, 61, NULL, 'F1', 'F2'
    UNION ALL Select 6, 62, 't', 'F3', 'F3'
    UNION ALL Select 6, 62, 'f', 'F4', 'F4'
    Select 'Before', * from @Usr_Sessions
    OP_Query:
    BEGIN TRAN
    UPDATE A SET is_ended_at_trustable = 't' from @usr_Sessions A-- Select * from @Usr_Sessions "a" --
    WHERE (
    EXISTS (
    SELECT 1
    FROM @usr_sessions "b"
    WHERE "a"."ended_at" = "b"."started_at"
    AND "a"."usr_space_id" = "b"."usr_space_id"
    AND "a"."account_id" = "b"."account_id"
    ) ) AND "a"."is_ended_at_trustable" IS NULL
    Select 'After 1', * from @Usr_Sessions
    ROLLBACK TRAN /* Just to reset test data to original form, so second query below runs against original data */
    Dodge_Self_Join:
    With X as
    Select *
    , count(case when started_at = ended_at and is_ended_at_trustable is null then 'x' else null end)
    over(partition by account_id, usr_space_id) as Updatable
    From @Usr_Sessions
    Update X
    set is_ended_at_Trustable = 'T'
    where Updatable > 0 -- EDIT -- fixed error, previously said "updatable = 1"
    Select 'After 2', * from @Usr_Sessions

  • Recursive Self Join

    Hi. I need to query the database of a document management system.   Documents are logically stored in folders in a tree structure and may be nested to arbitrary depth.  The FOLDER table lists the names and metadata of folders. 
    Ultimately, I want to join the FOLDER table ("f") to the DOCUMENT table ("d") to get a list of documents by folder.  The main thing I need help with is to build folder paths.  I don't necessarily even
    need to build full paths.  I would be happy just listing all the individual folders under the root, and the documents they contain.  I imagine to build folder paths involves a self join, but I don't know how to hadle arbitrary depth
    The first two columns of the FOLDER table are FOLDER_ID and PARENT_FOLDER_ID.  The data looks like this (where FOLDER_ID 1 represents the root folder):
    FOLDER_ID     PARENT_FOLDER_ID
    1                    null
    2                    1
    3                    1
    4                    1
    5                    2
    6                    2
    7                    1
    etc.
    Thanks for your help!

    See Itzik Ben-Gan examples dealing with such queries.
    CREATE TABLE Employees
      empid   int         NOT NULL,
      mgrid   int         NULL,
      empname varchar(25) NOT NULL,
      salary  money       NOT NULL,
      CONSTRAINT PK_Employees PRIMARY KEY(empid),
      CONSTRAINT FK_Employees_mgrid_empid
        FOREIGN KEY(mgrid)
        REFERENCES Employees(empid)
    CREATE INDEX idx_nci_mgrid ON Employees(mgrid)
    SET NOCOUNT ON
    INSERT INTO Employees VALUES(1 , NULL, 'Nancy'   , $10000.00)
    INSERT INTO Employees VALUES(2 , 1   , 'Andrew'  , $5000.00)
    INSERT INTO Employees VALUES(3 , 1   , 'Janet'   , $5000.00)
    INSERT INTO Employees VALUES(4 , 1   , 'Margaret', $5000.00) 
    INSERT INTO Employees VALUES(5 , 2   , 'Steven'  , $2500.00)
    INSERT INTO Employees VALUES(6 , 2   , 'Michael' , $2500.00)
    INSERT INTO Employees VALUES(7 , 3   , 'Robert'  , $2500.00)
    INSERT INTO Employees VALUES(8 , 3   , 'Laura'   , $2500.00)
    INSERT INTO Employees VALUES(9 , 3   , 'Ann'     , $2500.00)
    INSERT INTO Employees VALUES(10, 4   , 'Ina'     , $2500.00)
    INSERT INTO Employees VALUES(11, 7   , 'David'   , $2000.00)
    INSERT INTO Employees VALUES(12, 7   , 'Ron'     , $2000.00)
    INSERT INTO Employees VALUES(13, 7   , 'Dan'     , $2000.00)
    INSERT INTO Employees VALUES(14, 11  , 'James'   , $1500.00)
    The first request is probably the most common one:
     returning an employee (for example, Robert whose empid=7) 
    and his/her subordinates in all levels. 
    The following CTE provides a solution to this request:
    WITH EmpCTE(empid, empname, mgrid, lvl)
    AS
      -- Anchor Member (AM)
      SELECT empid, empname, mgrid, 0
      FROM Employees
      WHERE empid = 7
      UNION ALL
      -- Recursive Member (RM)
      SELECT E.empid, E.empname, E.mgrid, M.lvl+1
      FROM Employees AS E
        JOIN EmpCTE AS M
          ON E.mgrid = M.empid
    SELECT * FROM EmpCTE
    Using this level counter you can limit the number of iterations
     in the recursion. For example, the following CTE is used to return 
    all employees who are two levels below Janet:
    WITH EmpCTEJanet(empid, empname, mgrid, lvl)
    AS
      SELECT empid, empname, mgrid, 0
      FROM Employees
      WHERE empid = 3
      UNION ALL
      SELECT E.empid, E.empname, E.mgrid, M.lvl+1
      FROM Employees as E
        JOIN EmpCTEJanet as M
          ON E.mgrid = M.empid
      WHERE lvl < 2
    SELECT empid, empname
    FROM EmpCTEJanet
    WHERE lvl = 2
    As mentioned earlier, CTEs can refer to
     local variables that are defined within the same batch.
     For example, to make the query more generic, you can use 
    variables instead of constants for employee ID and level:
    DECLARE @empid AS INT, @lvl AS INT
    SET @empid = 3 -- Janet
    SET @lvl   = 2 -- two levels
    WITH EmpCTE(empid, empname, mgrid, lvl)
    AS
      SELECT empid, empname, mgrid, 0
      FROM Employees
      WHERE empid = @empid
      UNION ALL
      SELECT E.empid, E.empname, E.mgrid, M.lvl+1
      FROM Employees as E
        JOIN EmpCTE as M
          ON E.mgrid = M.empid
      WHERE lvl < @lvl
    SELECT empid, empname
    FROM EmpCTE
    WHERE lvl = @lvl
    Results generated thus far might be returned (but are not guaranteed to be), 
    and error 530 is generated. You might think of using the MAXRECURSION option 
    to implement the request to return employees who are two levels below 
    Janet using the MAXRECURSION hint instead of the filter in the recursive member
    WITH EmpCTE(empid, empname, mgrid, lvl)
    AS
      SELECT empid, empname, mgrid, 0
      FROM Employees
      WHERE empid = 1
      UNION ALL
      SELECT E.empid, E.empname, E.mgrid, M.lvl+1
      FROM Employees as E
        JOIN EmpCTE as M
          ON E.mgrid = M.empid
    SELECT * FROM EmpCTE
    OPTION (MAXRECURSION 2)
    WITH EmpCTE(empid, empname, mgrid, lvl, sortcol)
    AS
      SELECT empid, empname, mgrid, 0,
        CAST(empid AS VARBINARY(900))
      FROM Employees
      WHERE empid = 1
      UNION ALL
      SELECT E.empid, E.empname, E.mgrid, M.lvl+1,
        CAST(sortcol + CAST(E.empid AS BINARY(4)) AS VARBINARY(900))
      FROM Employees AS E
        JOIN EmpCTE AS M
          ON E.mgrid = M.empid
    SELECT
      REPLICATE(' | ', lvl)
        + '(' + (CAST(empid AS VARCHAR(10))) + ') '
        + empname AS empname
    FROM EmpCTE
    ORDER BY sortcol
    (1) Nancy
     | (2) Andrew
     |  | (5) Steven
     |  | (6) Michael
     | (3) Janet
     |  | (7) Robert
     |  |  | (11) David
     |  |  |  | (14) James
     |  |  | (12) Ron
     |  |  | (13) Dan
     |  | (8) Laura
     |  | (9) Ann
     | (4) Margaret
     |  | (10) Ina
    Best Regards,Uri Dimant SQL Server MVP,
    http://sqlblog.com/blogs/uri_dimant/
    MS SQL optimization: MS SQL Development and Optimization
    MS SQL Consulting:
    Large scale of database and data cleansing
    Remote DBA Services:
    Improves MS SQL Database Performance
    SQL Server Integration Services:
    Business Intelligence

  • Self join please help

    I would be very grateful if someone would show me show to use the self join, I understand what is does but just don't know how to use it. I have a question from a exercise but no answer so I can't check it the question is - using temporary labels to abbreviate table names, find all the staff that earn more than 'SONG'.
    here is the table
    STAFFID SNAME JOB MGR STARTDATE SAL COMM BRANCHID
    5963 SMITH ADMIN 5209 15-NOV-00 1600 20
    5994 BATES ASSISTANT 5896 20-FEB-01 1800 100 30
    5125 CHAN ASSISTANT 5896 22-FEB-02 1550 150 30
    5665 JONES MANAGER 5938 02-MAR-01 3100 20
    5465 WILSON ASSISTANT 5896 28-OCT-00 1250 140 30
    5896 HAYAT MANAGER 5938 01-MAY-01 3100 30
    5287 CLARK MANAGER 5938 09-JUL-02 3100 10
    5887 COSTA BUYER 5665 18-APR-04 3150 20
    5938 SHAW DIRECTOR 17-NOV-01 7000 10
    5484 TURNER ASSISTANT 5896 08-OCT-01 1550 0 30
    5678 KALIM ADMIN 5887 23-APR-04 1600 20
    5009 JAMES ADMIN 5896 03-DEC-01 1600 30
    5209 SONG BUYER 5665 03-JAN-02 3000 20
    5439 SIMPSON ADMIN 5287 23-FEB-02 1600 10
    Thanks in advanced :)
    Edited by: user11093259 on 01-Dec-2010 10:19

    Hi,
    Welcome to the forum!
    Always post your best attempt at solving the problem. You'll get more specific replies that will help you learn more, and it often clarifies what you're trying to do.
    Here's a typical self-join, using the scott.dept table (which you probably have avaialble).
    SELECT     l.dname          AS lower_dname
    ,     h.dname          AS higher_dname
    FROM     scott.dept     l
    JOIN     scott.dept     h  ON     l.dname     < h.dname
    ;Output:
    LOWER_DNAME    HIGHER_DNAME
    ACCOUNTING     OPERATIONS
    ACCOUNTING     RESEARCH
    ACCOUNTING     SALES
    OPERATIONS     RESEARCH
    OPERATIONS     SALES
    RESEARCH       SALESAs you can see, this pairs every higher_dname with every dname that is less than it.
    This is very similar to your problem. The main difference is, where the query above shows every possible higher_dname (and the lower_dnames related to it), you're interested in a single, specific higher value (and the rolws with lower values related to it). You can restrict the query to show only that one, specific higher values by adding a WHERE clause. Try it. If you get stuck, ask a more specific question, and, remember, post your code.

  • Performance Tuning - Self Join Issue

    Hi,
    The following query takes long time to execute. Is there any better way to
    re-writing the query to reduce the time it takes to execute.
    INSERT INTO TT_TEMP_MAINGUI_SP_PERCENT_MOV
    (prev_prc_dt,asset_id,pricing_pt_id,price_dt)
    SELECT max(tpm2.prc_dt),
    tpm2.asset_id ,
    tpm2.pricing_pt_id ,
    tpm1.prc_dt
    FROM t_prc_master tpm1,
    t_prc_master tpm2
    WHERE tpm1.prc_dt = '19-Dec-07'
    AND tpm1.asset_id = tpm2.asset_id
    AND tpm1.pricing_pt_id = tpm2.pricing_pt_id
    AND tpm2.prc_dt < tpm1.prc_dt
    AND tpm2.accept_flg = 'Y'
    AND tpm1.accept_flg = 'Y'
    AND EXISTS (SELECT 1 FROM t_temp_prcmov
    WHERE pca_flg = 'P'
    AND tpm1.pricing_pt_id = prc_pt_cntry_atyp)
    GROUP BY tpm2.asset_id, tpm2.pricing_pt_id,tpm1.prc_dt;
    select count(*) from t_prc_master
    where prc_dt = '19-Dec-07'
    COUNT(*)
    784161
    -- Here is the TKPROF Output
    INSERT INTO TT_TEMP_MAINGUI_SP_PERCENT_MOV
    (prev_prc_dt,asset_id,pricing_pt_id,price_dt)
    SELECT max(tpm2.prc_dt),
    tpm2.asset_id ,
    tpm2.pricing_pt_id ,
    tpm1.prc_dt
    FROM t_prc_master tpm1,
    t_prc_master tpm2
    WHERE tpm1.prc_dt = '19-Dec-07'
    AND tpm1.asset_id = tpm2.asset_id
    AND tpm1.pricing_pt_id = tpm2.pricing_pt_id
    AND tpm2.prc_dt < tpm1.prc_dt
    AND tpm2.accept_flg = 'Y'
    AND tpm1.accept_flg = 'Y'
    AND EXISTS (SELECT 1 FROM t_temp_prcmov
    WHERE pca_flg = 'P'
    AND tpm1.pricing_pt_id = prc_pt_cntry_atyp)
    GROUP BY tpm2.asset_id, tpm2.pricing_pt_id,tpm1.prc_dt
    call count cpu elapsed disk query current rows
    Parse 1 0.00 0.00 0 0 0 0
    Execute 1 226.01 317.50 1980173 4915655 805927 780544
    Fetch 0 0.00 0.00 0 0 0 0
    total 2 226.01 317.51 1980173 4915655 805927 780544
    Misses in library cache during parse: 1
    Optimizer goal: CHOOSE
    Parsing user id: 98 (PRSDBO)
    Rows Row Source Operation
    780544 SORT GROUP BY (cr=4915236 r=1980165 w=0 time=312751120 us)
    40416453 NESTED LOOPS (cr=4915236 r=1980165 w=0 time=245408132 us)
    783459 NESTED LOOPS (cr=956325 r=92781 w=0 time=17974163 us)
    55 TABLE ACCESS FULL T_TEMP_PRCMOV (cr=3 r=0 w=0 time=406 us)
    783459 TABLE ACCESS BY INDEX ROWID T_PRC_MASTER (cr=956322 r=92781 w=0 time=17782856 us)
    784161 INDEX RANGE SCAN PRC_DT_ASSET_ID (cr=412062 r=69776 w=0 time=14136725 us)(object id 450059)
    40416453 INDEX RANGE SCAN ASSET_DT_ACCEPT_FLG (cr=3958911 r=1887384 w=0 time=217215303 us)(object id 450055)
    Rows Execution Plan
    0 INSERT STATEMENT GOAL: CHOOSE
    780544 SORT (GROUP BY)
    40416453 NESTED LOOPS
    783459 NESTED LOOPS
    55 TABLE ACCESS GOAL: ANALYZED (FULL) OF 'T_TEMP_PRCMOV'
    783459 TABLE ACCESS GOAL: ANALYZED (BY INDEX ROWID) OF
    'T_PRC_MASTER'
    784161 INDEX GOAL: ANALYZED (RANGE SCAN) OF 'PRC_DT_ASSET_ID'
    (NON-UNIQUE)
    40416453 INDEX GOAL: ANALYZED (RANGE SCAN) OF 'ASSET_DT_ACCEPT_FLG'
    (UNIQUE)
    Could somebody help me in resolving the issue? It would be appreciated...

    Well, it's a bit of a mess to read. Please use the pre or code tags enclosed in [] next time to preserve the formatting of the code.
    First thing that looks 'bad' to me is
    WHERE tpm1.prc_dt = '19-Dec-07'which should be (i assume you want 2007 and not 1907)
    WHERE tpm1.prc_dt = TO_DATE('19-Dec-2007', 'DD-MON-YYYY');The next thing i'm very confused with is...why are you self joining the table? You should be able to just do this.....logically, it should produce the same results, though it's obviously not tested :D)
    SELECT
       max(tpm2.prc_dt),
       tpm2.asset_id ,
       tpm2.pricing_pt_id ,
       TO_DATE('19-Dec-2007', 'DD-MON-YYYY')  AS prc_dt
    FROM t_prc_master tpm2
    WHERE tpm2.prc_dt < TO_DATE('19-Dec-2007', 'DD-MON-YYYY')
    AND   tpm2.accept_flg = 'Y'
    AND   EXISTS   ( 
                      SELECT
                         NULL
                      FROM t_prc_master tpm1
                      WHERE tpm1.prc_dt          = TO_DATE('19-Dec-2007', 'DD-MON-YYYY')
                      AND   tpm1.asset_id        = tpm2.asset_id
                      AND   tpm1.pricing_pt_id   = tpm2.pricing_pt_id
                      AND   tpm1.accept_flg      = 'Y'                 
                      AND   tpm1.pricing_pt_id  IN (SELECT tmov.prc_pt_cntry_atyp FROM t_temp_prcmov tmov WHERE tmov.pca_flg = 'P')
    GROUP BY tpm2.asset_id, tpm2.pricing_pt_id, TO_DATE('19-Dec-2007', 'DD-MON-YYYY');Message was edited by:
    Tubby

  • Self Join and Aggregate Functions

    Hi all,
    I am trying a query in TOAD where I need to use an aggregate function MAX and a self join using a subquery. Its working fine when there is no aggregate function but when I tried to use the MAX function then its running for infi time. Is it because of the invalid joins? or because of the usage of the self join and aggregate func?
    The query contains some other tables too....
    Any one please help....
    Thanks in advance,
    G

    Toad will bring back a limited set of rows and present them to you giving the impression that the work is done. Adding an aggregate function requires the entire resultset to be traversed.
    Yes, post the 2 queries to verify what I am saying.

  • URGENT self join problem

    SQL> desc messages;
    Name Null? Type
    MESSAGEID NOT NULL NUMBER
    TITLE NOT NULL VARCHAR2(50)
    AUTHOR VARCHAR2(20)
    BODY NOT NULL VARCHAR2(4000)
    BOARD NUMBER
    THREAD NOT NULL NUMBER
    DATE_CREATED NOT NULL DATE
    This is the table i need to do a self join on, i know the two queries individually but i need to have them in one join,,,
    select b.title,b.boardid,m.messageid,m.title,m.author,m.date_created,m.body
    from messages m, boards b where b.boardid=m.board and m.thread=0 and b.boardid='198'
    and m.messageid='241';
    Thread title Author Starting message Last post
    Austrailia noel Austrailia 04/01/2005 21:22:35
    -----selects replies to the above message-----------
    select author,date_created,body
    from messages
    where board=198 and thread=241;
    AUTHOR DATE_CREATED BODY
    noel           05-JAN-05 Oz is played on clay
    noel 05-JAN-05 Oz played on grass
    noel 05-JAN-05     Oz played on grass
    This is the output that i want but at the moment thread title is repeated for all four rows returned.I want the output to look like a reply to a message like you see in some message boards on the web,,, you have the starting message and underneath you see the replies
    Thread title Author Starting message Last post
    Austrailia noel Austrailia 04/01/2005
    noel Oz is played on clay 05-JAN-05
    noel Oz played on grass 05-JAN-05
    noel Oz played on grass 05-JAN-05

    Please please please do not post duplicate threads. It makes it hard for people to follow what's going on. And it's annoying to boot. I think this is the third thread you have started on this topic.
    Please remember we are volunteers here, not Oracle employees. We do the best we can to answer queries in a timely fashion but if you want snappier service then I'm afraid you'll need to pay for a support contract.
    You posted a rejoinder to Barbara's answer to your other thread URGENT: combining two sql statements. That is sufficient to keep your issue in the public arena.
    Thank you for your co-operation.
    Regards, APC
    Issued in memory of the Rogue Moderators

  • Problem in Adhoc Query's set operation functionality.

    Hi Experts,
    I am facing problem executing Adhoc Query's set operation functionality.
    In Selection Tab, following operations are performed :-
    Execute a query and mark it as 'Set A'.(Say Hit list = X)
    Execute another query and mark it as 'Set B'.(Say Hit list = Y)
    In Set operation Tab, following operations are performed :-:-
    Carry out an Operations 'Set A minus Set B'.
    which results in Resulting Set = Z.
    Transfer the resulting set 'in hit list' and press the copy resulting set button.
    In Selection Tab, Hit list is populated with Z.
    And when output button is pressed, I get to see 'Y' list and not 'Z' list.
    Kindly help.
    Thanks.
    Yogesh

    Hi Experts,
    I am facing problem executing Adhoc Query's set operation functionality.
    In Selection Tab, following operations are performed :-
    Execute a query and mark it as 'Set A'.(Say Hit list = X)
    Execute another query and mark it as 'Set B'.(Say Hit list = Y)
    In Set operation Tab, following operations are performed :-:-
    Carry out an Operations 'Set A minus Set B'.
    which results in Resulting Set = Z.
    Transfer the resulting set 'in hit list' and press the copy resulting set button.
    In Selection Tab, Hit list is populated with Z.
    And when output button is pressed, I get to see 'Y' list and not 'Z' list.
    Kindly help.
    Thanks.
    Yogesh

  • Set operations in AdHoc Query - user settings

    Hi
    I am checking out the Set operations in AdHoc Query.  The documentation says you should save the setting "Set operations shown" as a user setting.  Could anyone advise me where this is set?  I can't find a parameter for it, and can't find it in the regular settings.
    Any help appreciated.
    Kirsten

    The save is automatic upon exiting Ad Hoc query.  Once you do "Show Set Operations", work on a query, save and exit, the next time you open Ad Hoc query, Set Operations tab is displayed by default.
    Regards,
    RN.

Maybe you are looking for

  • Issue while sending SMS from JavaMail in languages like Russian & Japanese

    Hi, We have a requirement to send multi lingual SMS to users mobile number. We are using JavaMail API for this. The only changes we have done to send SMS (instead of EMAIL) using a standard JavaMail code are – 1)     Use the suffix @sms after the mob

  • Integrate OC4J 10.0.x in Oracle Application Server 10g

    Ok, i have a Oracle Application Server 10g Enterprise Instance including Infrastructure on a Linux-Server. Its OC4J is a 9.0.4 OC4J following the J2EE 1.3 standard. So now Oracles offers a newer 10.0.x Developer Betarelease of OC4J wich will be in Pr

  • Start stop while loop with tab control

    I want to be able to start and stop a while loop by entering and leaving a tab.  I am using an event structure to do so but it doesn't seem elegant or the right way to do this.  The only way I was able to get it to kind of work is by unchecking the l

  • Why are pre-built graphics blurry on retina displays?

    I have designed multiple vector infographics in Inkpad (iPad app) and imported them into Adobe Muse. The desktop version of graphics looks great. iPad version is blurry and pixelated. No matter how I export the grpahics (ie: .png, .jpeg, .gif) it is

  • Upgrade from 10.4.11 to recent version?

    I am trying to upgrade my Mac OS version, currently 10.4.11. My software upgrade tells me I am completely up-to-date with my software. I am using a Mac Pro 2 x 3 GHz Dual-Core Intel Xeon machine. With 2 GB 667 MHz DDR2 FB-DIMM. What do I have to do t