Sys_connect_by_path_node ? [Can do this in ANSI SQL-99] - Hierarchy Query

Hi All,
A slighly more complex connect by problem (that can be done with ANSI SQL-99) looking for an oracle matching output.
Input Data: (Small example subset)
RootID | Parent_ID | FreeText
0 | 0     |
444 | 555 | ABC1
555 | 666 | DEF2
666 | 777 | GHI3
888 | 0 | JKL4
Output Wanted: (Small example subset)
RootID ParentID FreeText          LEVEL (Nesting)
444 |     555 |               |     1
444 |     666 |     ABC1          |     2
444 |     777 |     DEF2-ABC1     |     3
444 |     888 |     GHI3-DEF2-ABC1      | 4
444 |     0 |     JKL4-GHI3-DEF2-ABC1 | 5
Can be easily enough done with ANSI-99 SYNTAX (Not supported in Oracle using a recursive CTE)
Target platform Oracle 9i
ANSI-SQL 99 Syntax: (Not Supported on Oracle - but demonstrates the ANSI-SQL 99 compliant way of doing this)
;WITH Recurse(RootId, ParentID, FreeText, Level) AS
(SELECT td.RootID, td.ParentID, '' as FreeText, 1 as Level
from TEST_DATA td
where rootid = 444
union all
select Recurse.RootID, td2.ParentId, td2.freetext + '-' + recurse.freetext, recurse.level+1 as level
from TEST_DATA td2
select * from Recurse;
The problem: is to generating the freetext component correctly with oracle.
Can generate the freetext component the wrong way round using SYS_CONNECT_BY_PATH.
select connect_by_root(td.RootID), td.ParentID,
     CASE when level = 1 then ''
     ELSE
          SYS_CONNECT_BY_PATH(td.freetext, '-')
     END as FreeText, level
from test_data td
connect by td.RootID = prior td.ParentID
which gives:
RootID ParentID FreeText          LEVEL (Nesting)
444 | 555     | |     1
444 | 666 | ABC1 |          2
444 | 777 | ABC1-DEF2 | 3
444 | 888 | ABC1-DEF2-GHI3 | 4
444 | 0 | ABC1-DEF2-GHI3-JKL4 | 5
The problem is the freetext component is the wrong way round (the root node information always comes first).
Tried looking at running something like:
select connect_by_root(td.RootID), td.ParentID,
     CASE when level = 1 then ''
     ELSE
          td.freetext || '-' || FreeText2
     END as FreeText2, level
from test_data td
connect by td.RootID = prior td.ParentID
--> but unfortunatly the aliasing of the column cannot be used to perform this operation [cannot reference the aliased column FreeText2].
Is there a sys_connect_by_path_node? (The opposite of sys_connect_by_path)
Returns the path of a column value from node to root,
with column values separated by char for each row returned by CONNECT BY condition
Or another way to get to the output required?
Best Regards,
D

Not directly but there is a fairly common workaround using the undocumented REVERSE function.
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production
SQL> SELECT SYS_CONNECT_BY_PATH (ename, '/') enames,
  2         REVERSE (SYS_CONNECT_BY_PATH (REVERSE (ename), '/')) reverse_enames
  3  FROM   emps
  4  START WITH mgr IS NULL
  5  CONNECT BY PRIOR empno = mgr;
ENAMES                         REVERSE_ENAMES
/KING                          KING/
/KING/JONES                    JONES/KING/
/KING/JONES/SCOTT              SCOTT/JONES/KING/
/KING/JONES/SCOTT/ADAMS        ADAMS/SCOTT/JONES/KING/
/KING/JONES/FORD               FORD/JONES/KING/
/KING/JONES/FORD/SMITH         SMITH/FORD/JONES/KING/
/KING/BLAKE                    BLAKE/KING/
/KING/BLAKE/ALLEN              ALLEN/BLAKE/KING/
/KING/BLAKE/WARD               WARD/BLAKE/KING/
/KING/BLAKE/MARTIN             MARTIN/BLAKE/KING/
/KING/BLAKE/TURNER             TURNER/BLAKE/KING/
/KING/BLAKE/JAMES              JAMES/BLAKE/KING/
/KING/CLARK                    CLARK/KING/
/KING/CLARK/MILLER             MILLER/CLARK/KING/
14 rows selected.
SQL>

Similar Messages

  • Help me please ,I dont can solve this problem

    please How I can solve this problem?(SQL)
    Display each employee’s last name, hire date, and salary review date, which is the first Monday after
    six months of service. Label the column REVIEW. Format the dates to appear similar to “Monday,
    the Thirty-First of July, 2000.”
    Flickr: abbasovv's Photostream

    Where you get this task?  I didn't understand anything, really! what do you want to do? what is the purpose? to get next 6 months function ADD_MONTHS, to get next monday, tuesday ... use function NEXT_DAY, to get number of week use function TO_CHAR.
    WITH T AS(
    select to_date('17-JUN-1987','dd-mon-yyyy') D from dual union all
    select to_date('21-SEP-1989','dd-mon-yyyy') from dual union all
    select to_date('13-JAN-1993','dd-mon-yyyy') from dual union all
    select to_date('03-JUN-1990','dd-mon-yyyy') from dual union all
    select to_date('21-MAY-1991','dd-mon-yyyy') from dual union all
    select to_date('07-FEB-1999','dd-mon-yyyy') from dual union all
    select to_date('16-NOV-1999','dd-mon-yyyy') from dual )
    SELECT D,
           ADD_MONTHS(D,6),
           NEXT_DAY(ADD_MONTHS(D,6),'MONDAY'),
           TO_CHAR(ADD_MONTHS(D,6),'W'),
           TO_CHAR(ADD_MONTHS(D,6),'fmDay, fmdd fmMonth fmyyyy')
    FROM T
    WHERE TO_CHAR(ADD_MONTHS(D,6),'W') = 1
    Ramin Hashimzade

  • Error in Migration Db sql server to sql Azure, how i can fix this errors

    I get an error TOTAL_WRITE is not supported in current version when i try validate my database from sql server migration in to sql azure. How I can Fix this error migrate to sql azure
    Also I git this error sp_spaceused is not supported in current version of Azure SQL Database – Reynel Useche Velasco 22 mins ago
    StoredProcedure [dbo].[p_sizetables] -- 'db_name(' is supported only for the local database. You should test to verify the results are what you want. – Reynel Useche Velasco just now edit
    Reynel Alfredo Useche Velasco

    Hi Reynel,
    I see that you have posted this query on stack overflow.
    I would like to involve our SQL experts in this topic and get the best solution.
    As of now to my knowledge @@TOTAL_WRITE is not supported on SQL Azure.
    In the meantime, you can refer the below links for migrating your database from on-prem to Azure.
    https://msdn.microsoft.com/en-us/library/hh313125(v=sql.110).aspx
    https://msdn.microsoft.com/en-us/library/hh313129(v=sql.110).aspx
    Hope this helps you.
    Girish Prajwal

  • Can anyone solve this puzzle using SQL?

    Can anyone solve this puzzle using SQL?
    http://www.greylabyrinth.com/puzzle/puzzle182

    DylanB123 wrote:
    Took me almost 4 min just to get all the permutations/combinations using only dual. May try out the full thing when traffic does down on the DB.Well this looks like it gives the correct answer...
    SQL> select * from disks;
          DISK COLOUR
             1 WGYBRK
             2 WBYGKR
             3 WBGRKY
             4 WRGYKB
             5 WKGBYR
             6 WBKYGR
             7 WGKBYR
    7 rows selected.
    Elapsed: 00:00:00.04
    SQL> select   disk_perms,
      2           offset_1,
      3           offset_2,
      4           offset_3,
      5           offset_4,
      6           offset_5,
      7           offset_6,
      8           offset_7
      9    from   (select   permutations disk_perms
    10               from   (    select   replace (sys_connect_by_path (n, ','), ',')
    11                                       permutations
    12                             from   (    select   to_char (level) n
    13                                           from   dual
    14                                     connect by   level <= 7) yourtable
    15                       connect by   nocycle n != prior n)
    16              where   length (permutations) = 7) disk_permutations
    17           cross join
    18           (select   tab1.c offset_1,
    19                      tab2.c offset_2,
    20                      tab3.c offset_3,
    21                      tab4.c offset_4,
    22                      tab5.c offset_5,
    23                      tab6.c offset_6,
    24                      tab7.c offset_7
    25             from   (select   level - 1 as c from   dual connect by   level <= 6) tab1,
    26                    (select   level - 1 as c from   dual connect by   level <= 6) tab2,
    27                    (select   level - 1 as c from   dual connect by   level <= 6) tab3,
    28                    (select   level - 1 as c from   dual connect by   level <= 6) tab4,
    29                    (select   level - 1 as c from   dual connect by   level <= 6) tab5,
    30                    (select   level - 1 as c from   dual connect by   level <= 6) tab6,
    31                    (select   level - 1 as c from   dual  connect by   level <= 6) tab7) offset_combinations
    32           join disks d1 on d1.disk = substr(disk_perms,1,1)
    33           join disks d2 on d2.disk = substr(disk_perms,2,1)
    34           join disks d3 on d3.disk = substr(disk_perms,3,1)
    35           join disks d4 on d4.disk = substr(disk_perms,4,1)
    36           join disks d5 on d5.disk = substr(disk_perms,5,1)
    37           join disks d6 on d6.disk = substr(disk_perms,6,1)
    38           join disks d7 on d7.disk = substr(disk_perms,7,1)
    39    where substr( substr(d6.colour,offset_6+1)||substr(d6.colour,decode(offset_6,0,7,1),offset_1), 3,1) = substr( substr(d7.colour,offset_7+1)||substr(d7.colour,decode(offset_7,0,7,1),offset_7), 5,1)
    40    and   substr( substr(d5.colour,offset_5+1)||substr(d5.colour,decode(offset_5,0,7,1),offset_5), 2,1) = substr( substr(d7.colour,offset_7+1)||substr(d7.colour,decode(offset_7,0,7,1),offset_7), 5,1)
    41    and   substr( substr(d5.colour,offset_5+1)||substr(d5.colour,decode(offset_5,0,7,1),offset_5), 1,1) = substr( substr(d6.colour,offset_6+1)||substr(d6.colour,decode(offset_5,0,7,1),offset_5), 4,1)
    42    and   substr( substr(d4.colour,offset_4+1)||substr(d4.colour,decode(offset_4,0,7,1),offset_4), 1,1) = substr( substr(d7.colour,offset_7+1)||substr(d7.colour,decode(offset_7,0,7,1),offset_7), 4,1)
    43    and   substr( substr(d4.colour,offset_4+1)||substr(d4.colour,decode(offset_4,0,7,1),offset_4), 6,1) = substr( substr(d5.colour,offset_5+1)||substr(d5.colour,decode(offset_5,0,7,1),offset_5), 3,1)
    44    and   substr( substr(d3.colour,offset_3+1)||substr(d3.colour,decode(offset_3,0,7,1),offset_3), 6,1) = substr( substr(d7.colour,offset_7+1)||substr(d7.colour,decode(offset_7,0,7,1),offset_7), 3,1)
    45    and   substr( substr(d3.colour,offset_3+1)||substr(d3.colour,decode(offset_3,0,7,1),offset_3), 5,1) = substr( substr(d4.colour,offset_4+1)||substr(d4.colour,decode(offset_4,0,7,1),offset_4), 2,1)
    46    and   substr( substr(d2.colour,offset_2+1)||substr(d2.colour,decode(offset_2,0,7,1),offset_2), 5,1) = substr( substr(d7.colour,offset_7+1)||substr(d7.colour,decode(offset_7,0,7,1),offset_7), 2,1)
    47    and   substr( substr(d2.colour,offset_2+1)||substr(d2.colour,decode(offset_2,0,7,1),offset_2), 4,1) = substr( substr(d3.colour,offset_3+1)||substr(d3.colour,decode(offset_3,0,7,1),offset_3), 1,1)
    48    and   substr( substr(d1.colour,offset_1+1)||substr(d1.colour,decode(offset_1,0,7,1),offset_1), 3,1) = substr( substr(d2.colour,offset_2+1)||substr(d2.colour,decode(offset_2,0,7,1),offset_2), 6,1)
    49    and   substr( substr(d1.colour,offset_1+1)||substr(d1.colour,decode(offset_1,0,7,1),offset_1), 4,1) = substr( substr(d7.colour,offset_7+1)||substr(d7.colour,decode(offset_7,0,7,1),offset_7), 1,1)
    50    and   substr( substr(d1.colour,offset_1+1)||substr(d1.colour,decode(offset_1,0,7,1),offset_1), 5,1) = substr( substr(d6.colour,offset_6+1)||substr(d6.colour,decode(offset_6,0,7,1),offset_6), 2,1)
    51  /
    DISK_PERMS
      OFFSET_1   OFFSET_2   OFFSET_3   OFFSET_4   OFFSET_5   OFFSET_6   OFFSET_7
    5172643
             5          0          3          2          5          4          2
    Elapsed: 00:00:03.90
    SQL>If you take the positions as in
       1
    6   2
       7
    5   3
       4and the rotations (offsets) as anticlockwise based on my colour strings being in a clockwise order from the top.

  • I don't know how I can optimize this SQL

    Dear ALL:
    I don't know how I can optimize this SQL.
    Is it possible to make a better SQL or PL/SQL?
    Please let me know your good thought.
    Thank you.
    Sincerely,
    ===========================================================
    (SELECT     A, B, C, SUM(D) as D, AVG(E) as E
    FROM      T1, T2
    WHERE     T1.timestamp BETWEEN TO_DATE('00:00:00','HH24:MI:SS')
    AND TO_DATE('01:00:00','HH24:MI:SS')
    GROUP BY A, B, C
    UNION ALL
    (SELECT     A, B, C, SUM(D) as D, AVG(E) as E
    FROM      T1, T2
    WHERE     T1.timestamp BETWEEN TO_DATE('01:00:01','HH24:MI:SS')
    AND TO_DATE('02:00:00','HH24:MI:SS')
    GROUP BY A, B, C
    UNION ALL
    (SELECT     A, B, C, SUM(D) as D, AVG(E) as E
    FROM      T1, T2
    WHERE     T1.timestamp BETWEEN TO_DATE('02:00:01','HH24:MI:SS')
    AND TO_DATE('03:00:00','HH24:MI:SS')
    GROUP BY A, B, C
    UNION ALL
    (SELECT     A, B, C, SUM(D) as D, AVG(E) as E
    FROM      T1, T2
    WHERE     T1.timestamp BETWEEN TO_DATE('03:00:01','HH24:MI:SS')
    AND TO_DATE('04:00:00','HH24:MI:SS')
    GROUP BY A, B, C
    ORDER BY A ASC, B ASC, C ASC
    ===========================================================

    Dear Warren:
    Actually, for this query, it takes a few second to complete the query.
    But, I have to create several time period and I have to optimize the SQL.
    Time period is 1 hour, 30 min, 15 min, 5 min.
    That is,
    ===========================================================
    WHERE T1.timstamp BETWEEN TO_DATE('00:00:00','HH24:MI:SS')
    AND TO_DATE('01:00:00','HH24:MI:SS')
    UNION ALL
    WHERE T1.timestamp BETWEEN TO_DATE('23:00:01','HH24:MI:SS')
    AND TO_DATE('24:00:00','HH24:MI:SS')
    ===========================================================
    WHERE T1.timstamp BETWEEN TO_DATE('00:00:00','HH24:MI:SS')
    AND TO_DATE('00:30:00','HH24:MI:SS')
    UNION ALL
    WHERE T1.timestamp BETWEEN TO_DATE('23:30:01','HH24:MI:SS')
    AND TO_DATE('24:00:00','HH24:MI:SS')
    ===========================================================
    WHERE T1.timstamp BETWEEN TO_DATE('00:00:00','HH24:MI:SS')
    AND TO_DATE('00:15:00','HH24:MI:SS')
    UNION ALL
    WHERE T1.timestamp BETWEEN TO_DATE('23:45:01','HH24:MI:SS')
    AND TO_DATE('24:00:00','HH24:MI:SS')
    ===========================================================
    WHERE T1.timstamp BETWEEN TO_DATE('00:00:00','HH24:MI:SS')
    AND TO_DATE('00:05:00','HH24:MI:SS')
    UNION ALL
    WHERE T1.timestamp BETWEEN TO_DATE('23:55:01','HH24:MI:SS')
    AND TO_DATE('24:00:00','HH24:MI:SS')
    ===========================================================
    Do you know how this SQL is optimized?
    Thank you,

  • How can I translate this from PL/SQL into embedded SQL!?

    CURSOR TEMP1 is
    SELECT emp.fname fname, emp.lname lname, emp.ssn, dname,emp.salary salary, emp1.fname supervisor_fname, emp1.minit supervisor_mdlname,emp1.lname supervisor_lname FROM employee emp, employee emp1,department d
    WHERE emp.superssn=emp1.ssn(+) and emp.dno=dnumber order by ssn;
    PNTR_TEMP1 TEMP1%ROWTYPE;
    --calcualting values for the cursor TEMP1
    for PNTR_TEMP1 in TEMP1 loop
    fname:= PNTR_TEMP1.fname;
    lname:= PNTR_TEMP1.lname;
    ssn := PNTR_TEMP1.ssn;
    dname:=PNTR_TEMP1.dname;
    sup_name:=PNTR_TEMP1.supervisor_fname||' '|| PNTR_TEMP1.supervisor_mdlname||' '||PNTR_TEMP1.supervisor_lname;
    salary := PNTR_TEMP1.salary;
    n_deps:=0 ;
    /* how can I translate this to embedded SQL...I'm using C++*/

    Hi,
    you can follow this link to use cursor in Pro*c /C++
    http://www.csee.umbc.edu/help/oracle8/server.815/a68022/sql.htm
    Regards

  • How I can optimize this SQL query

    I require your help, I want to know how I can optimize this query
    SELECT
                    "F42119". "SDLITM" as "Code1"
                    "F42119". "SDAITM" as "Code2"
                    "F42119". "SDDSC1" as "Product"
                    "F42119". "SDMCU" as "Bodega"
                    Sum ("F42119". "SDSOQS" / 10000) as "Number",
                    Sum ("F42119". "SDUPRC" / 10000) as "preciou"
                    Sum ("F42119". "SDAEXP" / 100) as "Value",
                    Sum ("F42119". "SDUNCS" / 10000) as "CostoU"
                    Sum ("F42119". "SDECST" / 100) as "Cost"
                    "F4101". "IMSRP1" as "Division"
                    "F4101". "IMSRP2" as "classification",
                    "F4101". "IMSRP8" as "Brand"
                    "F4101". "IMSRP9" as "Aroma"
                    "F4101". "IMSRP0" as "Presentation"
                    "F42119". "SDDOC" as "Type",
                    "F42119". "SDDCT" as "Document",
                    "F42119". "SDUOM" as "Unit"
                    "F42119". "SDCRCD" as "currency"
                    "F0101". "ABAN8" as "ABAN8"
                    "F0101". "ABALPH" as "Customer"
                    "F0006". "MCRP22" as "Establishment"
    from          "PRODDTA". "F0101" "F0101"
                    "PRODDTA". "F42119" "F42119"
                    "PRODDTA". "F4101" "F4101"
                    "PRODDTA". "F0006" "F0006"
    where       "F42119". "SDAN8" = "F0101". "ABAN8"
      and         "F0006". "MCMCU" = "F42119". "SDMCU"
      and         "F4101". "IMITM" = "F42119". "SDITM"
      and         "F42119". "SDDCT" in ('RI', 'RM', 'RN')
      and         CAST (EXTRACT (MONTH FROM TO_DATE (substr ((to_date ('01-01-'| | to_char (round (1900 + (CAST ("F42119". "SDDGL" as int) / 1000))),' DD- MM-                YYYY ') + substr (to_char (CAST ("F42119". "SDDGL" as int)), 4,3) -1), 1,10))) AS INT) in : Month
    and          CAST (EXTRACT (YEAR FROM TO_DATE (substr ((to_date ('01-01-'| | to_char (round (1900 + (CAST ("F42119". "SDDGL" as int) / 1000))),' DD- MM-                YYYY ')+ Substr (to_char (CAST ("F42119". "SDDGL" as int)), 4,3) -1), 1,10))) AS INT) in: Year
    and          trim ("F0006". "MCRP22") =: Establishment
    and          trim ("F4101". "IMSRP1") =: Division
    Group By    "F42119". "SDLITM"
                    "F42119". "SDAITM"
                    "F42119". "SDDSC1"
                    "F4101". "IMSRP1"
                    "F42119". "SDDOC"
                    "F42119". "SDDCT"
                    "F42119". "SDUOM"
                    "F42119". "SDCRCD"
                    "F0101". "ABAN8"
                    "F0101". "ABALPH"
                    "F4101". "IMSRP2"
                    "F4101". "IMSRP8"
                    "F4101". "IMSRP9"
                    "F4101". "IMSRP0"
                    "F42119". "SDMCU"
                    "F0006". "MCRP22"
    I appreciate the help you can give me

    It seems to me that part of fixing it could be how you join the tables.
    Instead of the humongous where clause, put the applicable conditions on the join.
    You have
    from "PRODDTA". "F0101" "F0101"
    "PRODDTA". "F42119" "F42119"
    "PRODDTA". "F4101" "F4101"
    "PRODDTA". "F0006" "F0006"
    where "F42119". "SDAN8" = "F0101". "ABAN8"
    and "F0006". "MCMCU" = "F42119". "SDMCU"
    and "F4101". "IMITM" = "F42119". "SDITM"
    and "F42119". "SDDCT" in ('RI', 'RM', 'RN')
    and CAST (EXTRACT (MONTH FROM TO_DATE (substr ((to_date ('01-01-'| | to_char (round (1900 + (CAST ("F42119". "SDDGL" as int) / 1000))),' DD- MM- YYYY ') + substr (to_char (CAST ("F42119". "SDDGL" as int)), 4,3) -1), 1,10))) AS INT) in : Month
    and CAST (EXTRACT (YEAR FROM TO_DATE (substr ((to_date ('01-01-'| | to_char (round (1900 + (CAST ("F42119". "SDDGL" as int) / 1000))),' DD- MM- YYYY ')+ Substr (to_char (CAST ("F42119". "SDDGL" as int)), 4,3) -1), 1,10))) AS INT) in: Year
    and trim ("F0006". "MCRP22") =: Establishment
    and trim ("F4101". "IMSRP1") =: Division
    INSTEAD try something like
    from JOIN "PRODDTA". "F0101" "F0101" ON "F42119". "SDAN8" = "F0101". "ABAN8"
    JOIN "PRODDTA". "F42119" "F42119" ON "F0006". "MCMCU" = "F42119". "SDMCU"
    JOIN "PRODDTA". "F4101" "F4101" ON join condition
    JOIN "PRODDTA". "F0006" "F0006" ON join condition.
    Not sure exactly how you need things joined, but above is the basic idea. Remove criteria for joining the tables from the WHERE clause and put them
    in the join statements. That might clean things up and make it more efficient.

  • Differences between ANSI SQL and Oracle 8/9

    Hallo,
    i'm looking for good online texts or books concerning the problem "Differences between ANSI SQL and different database implementations (ORACLE, Informix, MySQL...)" I want to check a program written in C (with ESQL) that works with an Informix-DB. In this code i want to find code that is specific to the Informix-DB. I want to change the database, so all the code should be independent from a DB. Does anybody know texts or books concerning this problem?
    thx
    Marco Seum

    Basically there is syntax difference between both of them.
    Lets say i want to join two table EMP and DEPT based on DEPTNO.
    With Oracle SQL format its like this.
    select e.*
      from emp e, dept d
    where e.deptno = d.deptnoHere the joining condition goes in the WHERE clause.
    With ANSI SQL format its like this.
    select e.*
      from emp e
      join dept d
        on e.deptno = d.deptnoHere the join condition is mentioned separately and not in WHERE clause.
    Oracle supports ANSI SQL starting from 9i version.
    You can read more about the syntax difference Here

  • What is Difference between ANSI SQL and ORACLE SQL

    Hi,
    I am going to take the assesment test for ANSI SQL Programming before that i want to know any difference between ANSI SQL and ORACLE SQL?
    I am studying for SQL but the test will be ANSI SQL please let me give an idea about the both.
    Thanks
    Merina Roslin

    Basically there is syntax difference between both of them.
    Lets say i want to join two table EMP and DEPT based on DEPTNO.
    With Oracle SQL format its like this.
    select e.*
      from emp e, dept d
    where e.deptno = d.deptnoHere the joining condition goes in the WHERE clause.
    With ANSI SQL format its like this.
    select e.*
      from emp e
      join dept d
        on e.deptno = d.deptnoHere the join condition is mentioned separately and not in WHERE clause.
    Oracle supports ANSI SQL starting from 9i version.
    You can read more about the syntax difference Here

  • ANSI SQL Syntax - What belongs to join-clause and what to where-clause

    Hello,
    we currently have a discussion about the ANSI SQL Syntax where we do not agree what belongs to the join clause and what belongs to the where clause in an ANSI Sytnax SQL Query.
    Lets say there is a query like this:
    +SELECT *+
    FROM employees emp, departments dept
    WHERE emp.dept_country = dept.dept_country
    AND emp.dept_name = dept.dept_name
    AND dept.dept_type = 'HQ'
    AND emp.emp_lastname = 'Smith'
    Primary key of the departments table is on the columns dept_country, dept_name and dept_type. We have a Oracle database 10g.
    Now I have rewritten the query to Ansi Syntax:
    +SELECT *+
    FROM employees emp
    JOIN departments dept
    ON emp.dept_country = dept.dept_country AND emp.dept_name = dept.dept_name
    WHERE dept.dept_type = 'HQ'
    AND emp.emp_lastname = 'Smith'
    Another developer says that this is not completely correct, every filter on a column that belongs to the primary-key of the joined table has to be in the join clause, like this:
    +SELECT *+
    FROM employees emp
    JOIN departments dept
    +ON emp.dept_country = dept.dept_country AND emp.dept_name = dept.dept_name AND dept.dept_type = 'HQ'
    WHERE emp.emp_lastname = 'Smith'
    Can somebody tell me which on is correct?
    Is there any definition for that? I couldn't find it in the Oracle Database definition.
    I just found out the names of the ANSI documents here: http://docs.oracle.com/cd/B19306_01/server.102/b14200/ap_standard_sql001.htm#i11939
    I had a look at the ANSI webstore but there you have to buy the PDF files. In my case thats exaggerated because both of the Queries work and i am just interessted if there is one correct way.
    Thank you in advance
    Marco

    Hi,
    As i guideline i would say, answer the question: should the result of the join be filtered or should only filtered rows be joined from a particular table?
    This is helpful in the case of outer joins also, for inner joins it doesnt matters as said already be former posters, where there may be hughe semantical differences depending of where the predicates are placed.
    From performance view, if we talk about oracle, take a look a the execution plans. You will see that there is (probably) no difference in case of inner joins. Even in case of outer joins the optimizer pushes the predicate as a filter towards the table if it semantically possible.
    Regards

  • OWB 10.2.0.4 ANSI SQL join problem

    Hi
    Its seams to me, that in OWB 10.2.0.4 there is something broken with ANSI SQL joins and instead of ANSI joins there is used oracle SQL joins only. Maybe someone can point some solutions? I can’t rewrite all mappings with union and other operators. And manually pl/sql editing also would be big problem.

    "Am I correct in assuming you did not code ANSI joins?" -> yes, i am coding Oracle SQL joins and with this option just generating ANSI joins.
    With ANSI SQL join you can use OR and IN operands (and code looks more readable).
    It is question of performance (so for example 80% of dataset you can join by one column other 15% by second etc ..). So this all can be rewritten also in Split->join->union all, but if you have several such joins, this will be painfully.

  • Generate ANSI SQL with Oracle IKM

    Is it possible for ODI to generate ANSI SQL with the Oracle IKM?
    I have used ANSI joins in a filter in an interface, now when I run the interface I get the error: ORA-25156: old style outer join (+) cannot be used with ANSI joins.
    I would prefer to use ANSI joins in my filters instead of the old style (+) syntax. Is this possible?

    Sure,
    Go to topology, edit your Oracle technology , on SQL tab change it over to ordered joins - clause location - From , you can specify the keywords left join, right join, full outer join etc to get rid of your '(+)'

  • Help on - convert ansi sql to oracle sql

    hi gurus,
    i'm try'g to convert ansi sql to oracle sql.
    but i'm getting an error. can u please let me know, if i can convert it or is it better to use ansi sql!
    original code in ansi format::
    select distinct bfc.NBR_SEQ, bfc.IDN_ENTITY, bfc.CDE_TYPE_ENTITY, n.CDE_STATUS,
             gec.idn_group as idn_parent_id, bfc.IDN_FUNC_BUSS,
             case when bfc.CDE_TYPE_ENTITY = 'P'  OR bfc.CDE_TYPE_ENTITY = 'A' then
                PKG_FW_NVGTR.GET_NAM_PAGE(bfc.IDN_ENTITY)
              else
                PKG_FW_NVGTR.GET_NAM_GROUP(bfc.IDN_ENTITY)
             end as ENTITY_NAM,
             p.Category, p.Display_Txt, p.show_in_nav, p.page_uri
      from
        T_BUSS_FUNC_ENTITY_CREF bfc
        inner join t_buss_func bf on bfc.idn_func_buss = bf.idn_func_buss
        inner join t_entity_prog_cref epc on bfc.idn_entity = epc.idn_entity and bfc.cde_type_entity = epc.cde_type_entity
        left outer join t_page p on bfc.idn_entity = p.idn_page
        left outer join t_group_entity_cref gec on bfc.idn_entity = gec.idn_entity and bfc.cde_type_entity = gec.cde_type_entity
        left outer join t_nvgtr n on bfc.idn_entity = n.idn_entity and bfc.cde_type_entity = n.cde_type_entity
      where
        BF.nam_func_buss = 'CP' AND--P_NAM_FUNC_BUSS and
        epc.cde_program in
          ( select p.cde_program from t_program p where p.nam_program in (
              SELECT * FROM TABLE (CAST(PKG_FW_NVGTR.FN_GET_ARRAY_FROM_COMMA_LIST('LC', ',') AS TYP_ARRAY))))
      order by
        bfc.NBR_SEQ;tried to convert into oracle
    SELECT DISTINCT bfc.NBR_SEQ,
                 bfc.IDN_ENTITY,
                 bfc.CDE_TYPE_ENTITY,
                 n.CDE_STATUS,
                 gec.idn_group as idn_parent_id,
                 bfc.IDN_FUNC_BUSS,
                 case when bfc.CDE_TYPE_ENTITY = 'P'  OR bfc.CDE_TYPE_ENTITY = 'A' then
                             PKG_FW_NVGTR.GET_NAM_PAGE(bfc.IDN_ENTITY)
                           else
                             PKG_FW_NVGTR.GET_NAM_GROUP(bfc.IDN_ENTITY)
                 end as ENTITY_NAM,
                 p.Category,
                 p.Display_Txt,
                 p.show_in_nav,
                 p.page_uri
    FROM    T_BUSS_FUNC_ENTITY_CREF bfc,
                 T_BUSS_FUNC bf,
                 T_ENTITY_PROG_CREF epc,
                 T_PAGE p,
                 T_GROUP_ENTITY_CREF gec,
                 T_NVGTR n
    WHERE bfc.IDN_FUNC_BUSS = bf.IDN_FUNC_BUSS
    AND bfc.IDN_ENTITY = epc.IDN_ENTITY
    AND bfc.CDE_TYPE_ENTITY = epc.CDE_TYPE_ENTITY
    AND bfc.IDN_ENTITY(+) = p.IDN_PAGE
    AND bfc.IDN_ENTITY(+) = gec.IDN_ENTITY
    AND bfc.CDE_TYPE_ENTITY(+) = gec.CDE_TYPE_ENTITY
    AND bfc.IDN_ENTITY(+) = n.IDN_ENTITY
    AND bfc.CDE_TYPE_ENTITY(+) = n.CDE_TYPE_ENTITY
    AND BF.nam_func_buss = 'CP' AND--P_NAM_FUNC_BUSS and
        epc.cde_program in
          ( select p.cde_program from t_program p where p.nam_program in (
              SELECT * FROM TABLE (CAST(PKG_FW_NVGTR.FN_GET_ARRAY_FROM_COMMA_LIST('LC', ',') AS TYP_ARRAY))))
                   order by
                     bfc.NBR_SEQ;error is
    ORA-01417: a table may be outer joined to at most one other tableso how can i convert it?
    thanks

    user642856 wrote:
    explain plan for this select statement
    ID         PID       Operation                                                                                  Name                                                                Rows    Bytes    Cost     CPU Cost          IO Cost Temp space      IN-OUT  PQ Dist PStart   PStop
    0                      SELECT STATEMENT                                                                                                                                       10M                  1183M  570694 33G      567917                                                  
    1          0            SORT UNIQUE                                                                                                                                                            10M                  1183M  287940 17G      286502 2607M                                      
    2          1              HASH JOIN                                                                                                                                                   10M                  1216M  179       1G        84                                                          
    3          2                COLLECTION ITERATOR PICKLER FETCH   PKG_FW_NVGTR.FN_GET_ARRAY_FROM_COMMA_LIST                                                                                                                         
    4          2                HASH JOIN OUTER                                                                                                                         2693             299K     58         34M      55                                                          
    5          4                  HASH JOIN OUTER                                                                                                                                   37                     3959     11         24M      9                                                           
    6          5                    HASH JOIN OUTER                                                                                                                     37                         3663     10         18M      8                                                           
    7          6                      HASH JOIN                                                                                                                               37                         1147     7          12M      6                                                           
    8          7                        HASH JOIN                                                                                                                             59                         1180     5          6060823            4                                                           
    9          8                          NESTED LOOPS                                                                                                       2                      24                     3          15843   3                                                           
    10         9                            TABLE ACCESS BY INDEX ROWID  T_BUSS_FUNC             1                      6                      1             8341     1                                                           
    11         10                             INDEX UNIQUE SCAN                                UK_NAM_FUNC_BUSS 1                       0                      1050     0                                                           
    12         9                            TABLE ACCESS FULL                                             T_PROGRAM                2                      12             2          7501     2                                                           
    13         8                          INDEX FULL SCAN                            PK_T_ENTITY_PROG_CREF      59                     472       1             18921   1                                                           
    14         7                        TABLE ACCESS FULL                         T_BUSS_FUNC_ENTITY_CREF  37                     407       2             14891   2                                                           
    15         6                      TABLE ACCESS FULL                           T_PAGE                                                           26                     1768     2          14141   2                                                           
    16         5                    INDEX FULL SCAN                                              UK_UNIQUE_GROUP_DEPENDENT 26              208             1          12321   1                                                           
    17         4                  TABLE ACCESS FULL                                           T_NVGTR                                                          6986             47K      46         3179613            46                                                           as you can see.. cpu cost is in 33G..
    is there any better way?
    thanksCan you run this in a session please:
    ALTER SESSION set optimizer_dynamic_sampling = 4;Then run an explain plan again.
    And you have a function in there - PKG_FW_NVGTR.FN_GET_ARRAY_FROM_COMMA_LIST - which isn't helping things.

  • Converting oracle join to Ansi sql join

    Hi Guys,
    I am new to SQL and trying to convert the following Oracle query (joins) into ANSI sql joins...Can someone please help me?
    SELECT M.EXTERNALCODE, M.NAME AS MNAME, SC.BIRIM, SM.TRANSACTIONDATE, SMD.AMOUNT,
    SMD.UNITPRICE, SM.ID AS SMID, SMD.ID AS SMDID, F.NAME AS FNAME,
    IFNULL (SMD.AMOUNT, 0, SMD.AMOUNT) * IFNULL (SMD.UNITPRICE, 0, SMD.UNITPRICE) AS TOTALPRICE, SMD.AMOUNT AS RECEIVED_QUANTITY,
    PD.ORDERID, PD.AMOUNT QUANTITY, PO.PROCESSDATE
    FROM STOCKMAINTRANSACTION SM,
    STOCKMAINTRANSACTIONDETAIL SMD,
    MATERIAL M,
    STOCKCARD SC,
    FVSTOCK FVS,
    FIRM F,
    PURCHASEORDER PO,
    PURCHASEORDERDETAIL PD,
    PURCHASEORDERDETAILSUPPLIED PDS
    WHERE SM.ID = SMD.MAINTRANSACTIONID
    AND SMD.MATERIALID = M.ID
    AND SMD.STOCKCARDID = SC.ID
    AND SM.PROPREF = FVS.RECORDID(+)
    AND FVS.FIELDID(+) = 2559
    AND FVS.FLEVEL(+) = 'F'
    AND F.ID(+) = SUBSTR (FVS.FVALUE, 1, 9)
    AND SM.TRANSDEFID in (999,2329,2344,2370,150000903,150005362)
    AND SMD.CANCELLED = 0
    AND SMD.STOCKUPDATED = 1
    AND SMD.ID = PDS.STOCKMAINTRANSACTIONDETAILID
    AND PDS.ORDERDETAILID = PD.ORDERDETAILID
    AND PO.ORDERID = PD.ORDERID
    AND (M.ID = {@MATERIALID@} OR {@MATERIALID@} = 0)
    AND (SM.STOREID = {@STOREID@} OR {@STOREID@} = 0)
    AND (F.ID = {@SUPPLIERID@} OR {@SUPPLIERID@} = 0)
    AND SM.TRANSACTIONDATE BETWEEN {@STARTDATE@} AND {@ENDDATE@}
    ORDER BY F.NAME, M.EXTERNALCODE, SM.TRANSACTIONDATE
    Really appreciate the help!
    Thanks.

    Hi,
    Welcome to the forum!
    To convert to ANSI syntax, replace join conditions in the WHERE clause
    FROM           x
    ,             y
    WHERE         x.x1  = y.y1
    AND           x.x2  = y.y2with ON conditions in the FROM clause:
    FROM           x
    JOIN             y   ON    x.x1  = y.y1
                             AND   x.x2  = y.y2In inner joins, conditions that do not reference 2 tables are not really join conditions, so it doesn't matter if they are in the FROM clause or in the WHERE clause.
    In your case
    SM.TRANSDEFID in (999,2329,2344,2370,150000903,150005362)could be part of a join condition involving sm, or it could be in the WHERE clause. Most people find it clearer if 1-table conditions like this are in the WHERE clause.
    Again, this only applies to inner joins. For outer joins, all conditions that apply to a table that may lack matching rows must be included in the FROM clause, like this:
    LEFT OUTER JOIN  fvstock   fvs  ON   sm.propref       = fvs.recordid
                                    AND  fvs.fieldid  = 2559
                        AND  fvs.flevel   = 'F'Try it.
    If you have trouble, post your best attempt, along with CREATE TABLE and INSERT statements for a little sample data from all the tables involved, and the results you want from that data. Simplify the problem. Post only the tables and columns that you don't know how to handle.
    See the forum FAQ {message:id=9360002}
    user8428528 wrote:
    AND (M.ID = {@MATERIALID@} OR {@MATERIALID@} = 0)
    AND (SM.STOREID = {@STOREID@} OR {@STOREID@} = 0)
    AND (F.ID = {@SUPPLIERID@} OR {@SUPPLIERID@} = 0)
    AND SM.TRANSACTIONDATE BETWEEN {@STARTDATE@} AND {@ENDDATE@}This is not valid Oracle SQL. Is {@MATERIALID@} some kind of variable?

  • ANSI SQL to Oracle Old SQL conversion

    I need help to convert this ANSI SQL Query to Oracle Old school (With inline views and =(+) joins and where clasuses)
    CUrrent Query and new one should return same resultset
    ---------------------------------Query Start----------------------------------------------------
    SELECT COUNT(*)
    FROM
    SELECT
    'XXXXXX' as Big_Boss,
    da.Direct,
    da.Director,
    da.Manager,
    da.SubArea,
    da.Project,
    da.Project_Name,
    da.Project_Class,
    da.HISL,
    da.Resource_Name,
    da.Resource_Status,
    da.mon,
    to_char(sysdate, 'dd-Mon-YYYY') AS "Current_Date",
    DECODE(da.Project, NULL, 0, round(da.Slice / da.month_total, 2)) as
    "Approved_Demand",
    SUM(da.Availability) as "Headcount"
    FROM
    SELECT
    w.level4_name AS Direct,
    w.level5_name AS Director,
    w.level6_name AS Manager,
    w.level7_name AS SubArea,
    INV.Code as Project,
    inv.name as Project_Name,
    det.hum_project_gate as Project_Class,
    r.id AS HISL,
    r.full_name as Resource_Name,
    lookup.lookup_code as Resource_Status,
    alc.slice AS Slice,
    alc.slice_date as Mon,
    avl.slice AS month_total,
    alc.slice / avl.slice as FTE,
    count(distinct r.id) AS Availability
    FROM
    nbi_dim_obs w,
    prj_blb_slices_m_avl avl,
    prj_obs_units obs,
    cmn_lookups lookup,
    srm_resources r
    **************   Section to be Converted   ***************************----------
    ----------------------------Start----------------------------------------------------
    left outer join(prj_resources t inner join srm_resources res on
    t.prprimaryroleid = res.id) on r.id = t.prid
    left outer join(prj_blb_slices_m_alc alc
    left outer join(prteam tm
    inner join(inv_investments INV inner join odf_ca_project det on det.id = inv.id
    and det.hum_project_gate = 'approved_for_development') on tm.prprojectid = INV.ID
    and INV.Is_Active = 1) on alc.prj_object_id = tm.prid
    and alc.investment_id = inv.id) on alc.resource_id = t.prid
    --------------------------------------End--------------------------------------------
    -- inner join prj_blb_slices_m_avl avl on alc.resource_id = avl.prj_object_id
    -- inner join prj_obs_units obs on res.unique_name = obs.unique_name
    -- inner join nbi_dim_obs w on w.level7_unit_id = obs.id
    WHERE
    w.obs_type_name = 'Workgroup'
    AND alc.slice > 0
    AND alc.slice_date = avl.slice_date
    AND r.is_active = 1
    AND r.person_type = lookup.id
    AND w.level7_unit_id = obs.id
    AND alc.resource_id = avl.prj_object_id
    AND res.unique_name = obs.unique_name
    GROUP BY
    w.level4_name
    , w.level5_name
    , w.level6_name
    , w.level7_name
    , r.id
    , r.full_name
    , lookup.lookup_code
    , inv.code
    , inv.NAME
    , det.hum_project_gate
    , alc.slice_date
    , alc.slice
    , avl.slice
    ) DA
    GROUP BY
    da.direct
    , da.director
    , da.manager
    , da.subarea
    , da.project_class
    , da.hisl
    , da.resource_name
    , da.resource_status
    , da.project
    , da.Project_Name
    , da.mon
    , da.availability
    , da.slice
    , da.month_total
    ORDER BY
    da.direct
    , da.director
    , da.manager
    , da.subarea
    -------------------------------Query End----------------------------------------------------------

    Joins are joins ... what do you mean by "nested" joins?
    If you are concerned about outer joins that can be performed using ANSI syntax that are not supported in the classic Oracle syntax then use in-line view and outer join the views.
    If your code was properly formatted it would be possible for someone to read it and possibly see what you are seeing.
    Read the FAQ page and learn to format your posted code.

Maybe you are looking for

  • Hierarchy Node Authorization Issue

    Hello Experts, I am trying to restrict a user from seeing the complete hierarchy. The user should only be able to see the text node "text1" and below. I did the following: 1) Using Tcode RSECADMIN  I created an Authorization Object ZTEST2 for 0COMP_C

  • MSN Messenger and Address Book don't work in one account

    I recently succumbed to pressure from my daughter to set up MSN Messenger for her, but couldn't make it work in her account. A window appeared for reporting the problem to Microsoft, and when I looked in More Information, it seemed to be something to

  • Purchase Order Net Price not editable after GR/IR

    Hi Friends! I am facing a problem that, I want the price of the Purchase Order document should not be changed after the GR or IR is posted for this document. I have checked that making the net price field as display or M/06 is not the solution of the

  • GROUP MESSAGING ON iPHONE??

    Hello to all. I been looking around to try to find a "topic" associated with "group messaging" but no luck. My questions is does iPhone have "Group Messaging". So I can send 1 message to about 4 different people in my contact list? I know you can do

  • How to create IDOC for customer defined table

    hi, How to create IDOC for customer defined table Records and how to send this IDOC to target system.   what message type will be used and on receiving system how to post these records.   thankx.   pillac.