Simple ANSI syntax Outer Join question

Ask a Question related to Coldfusion Database Access, Design and Development.

  1. #1

    Default Simple ANSI syntax Outer Join question

    Hello. I have an application that uses many *= and =* outer joins in its
    queries. In order to convert an older query into the proper syntax, I am
    examining which ones we'll have to do this with.

    Attached is the old code, followed by the first iteration (non-functional) of
    SQL that is attempting to use LEFT OUTER JOIN syntax.... I have had a rough
    time trying to find documentation for a query in which one table has multiple
    outer joins.

    What is the conceptual or syntactical error here? Thanks in advance!

    SELECT tbl_user.*, tbl_user_level.user_level, tbl_user_scope.scope_type,
    tbl_program.program, tbl_program.program_id, tbl_site.site, tbl_site.site_id

    FROM tbl_user, tbl_user_level, tbl_user_scope, tbl_program, tbl_site
    WHERE tbl_user.level_id = tbl_user_level.ID
    AND tbl_user.scope_id = tbl_user_scope.ID
    AND tbl_user.scope_program_id *= tbl_program.ID
    AND tbl_user.scope_site_id *= tbl_site.ID



    SELECT tbl_user.*, tbl_user_level.user_level, tbl_user_scope.scope_type,
    tbl_program.program, tbl_program.program_id, tbl_site.site, tbl_site.site_id

    FROM tbl_user, tbl_user_level, tbl_user_scope

    LEFT OUTER JOIN tbl_program ON tbl_user.scope_program_id = tbl_program.ID
    LEFT OUTER JOIN tbl_site ON tbl_user.scope_site_id = tbl_site.ID

    WHERE tbl_user.level_id = tbl_user_level.ID
    AND tbl_user.scope_id = tbl_user_scope.ID

    Captain Special Guest

  2. Similar Questions and Discussions

    1. Outer join?
      Sometimes I need to make queries and join tables, knowing that the other table rows are not always available. Example: I do SELECT...
    2. OUTER JOIN
      I can't get this outer join to work, It worked when i made it into a inner join Select * FROM dbo.tEmployee OUTER JOIN dbo.tEmployeeaccess ON...
    3. FULL OUTER JOIN
      Will Cold Fusion process a FULL OUTER JOIN in a cfquery?
    4. SQL outer join syntax error
      I'm not kidding, the only reason yesterday you didn't hear from me was because I wasn't coding, but today I am doing something quick, and yes, as...
    5. Newbie - Easy (I think) SQL Syntax Question, 3 table join
      I have three identical tables, t1, t2, t3 Each table contains a complete list of files on a particular server. One of the fields in each table...
  3. #2

    Default Re: Simple ANSI syntax Outer Join question

    Answer found immediately after post. For posterity, here it is: use ANSI the
    whole way through:

    SELECT tbl_user.*, tbl_user_level.user_level, tbl_user_scope.scope_type,
    tbl_program.program, tbl_program.program_id, tbl_site.site, tbl_site.site_id

    FROM tbl_user

    LEFT OUTER JOIN tbl_program ON tbl_user.scope_program_id = tbl_program.ID
    LEFT OUTER JOIN tbl_site ON tbl_user.scope_site_id = tbl_site.ID
    JOIN tbl_user_level ON tbl_user.level_id = tbl_user_level.ID
    JOIN tbl_user_scope ON tbl_user.scope_id = tbl_user_scope.ID

    Captain Special Guest

  4. #3

    Default Re: Simple ANSI syntax Outer Join question

    Couple of things. First, you might consider using table name aliases so that
    you can use those to prefix your column names rather than having to repeat the
    entire table name on each column. Also, since you are using ANSI-92 syntax, you
    will need to use INNER JOINs on your other tables.

    Phil




    SELECT tu.*,
    tul.user_level,
    tus.scope_type,
    tp.program,
    tp.program_id,
    ts.site, ts.site_id
    FROM tbl_user tu INNER JOIN tbl_user_scope tus ON tu.scope_id = tus.ID
    LEFT JOIN tbl_program tp ON tu.scope_program_id = tp.ID
    LEFT JOIN tbl_site ts ON tu.scope_site_id = ts.ID

    paross1 Guest

  5. #4

    Default Re: Simple ANSI syntax Outer Join question

    paross1,

    Thanks for your suggestions. It was your suggestion (in another thread) that
    I switch some old queries to ANSI-92 syntax in the first place, so I really
    appreciate your helping me see that through. Along those lines, I am trying to
    migrate 167 templates with *= style joins over to ANSI-92, based on your
    suggestion.

    I have already learned a lot about the new syntax, but there are some areas
    I'm having a hard time finding documentation for. Do you have some recommended
    SQL reading? I have actually been able to go very far with Forta's Teach
    Yourself SQL in 10 Minutes, and O'Reilly's SQL in a Nutshell. And, in the
    meantime, could you give me a sentence or two on why this doesn't work?



    SELECT tbl_family.ID, tbl_family.assigned_id, tbl_family.contact_person,
    COUNT(tbl_adult.ID) AS num_adults
    FROM tbl_family
    LEFT OUTER JOIN tbl_adult ON AND tbl_family.ID = tbl_adult.family_ID

    WHERE tbl_family.site_id = <CFQUERYPARAM VALUE="#form.siteID#"
    CFSQLTYPE="CF_SQL_INTEGER">
    AND tbl_adult.is_enrolled = 'No'
    GROUP BY tbl_family.assigned_id, tbl_family.ID, tbl_family.contact_person

    Captain Special Guest

  6. #5

    Default Re: Simple ANSI syntax Outer Join question

    Since I started out as an Oracle developer, and Oracle didn't implement this
    syntax until version 9i, I was rather late in learning how to write queries
    this way myself, as Oracle had its own proprietary way of doing outer joins,
    etc. Having said that, my primary reference for MSSQL has been the good old
    Books Online that you install with Enterprise Manager, or that you can download
    from Microsoft.

    Phil

    paross1 Guest

  7. #6

    Default Re: Simple ANSI syntax Outer Join question

    Thank you!
    Captain Special Guest

  8. #7

    Default Re: Simple ANSI syntax Outer Join question

    I'd rather post this here than start another thread. i have a query that isn't
    converting nicely

    I will first post the original version, then my attempt at making it ANSI-92
    conformant. The first works just as it should, but the second returns no
    results if there are no records in tbl_part_adult for a particular adult_ID for
    that fiscal year (as selected by two form variables that are part of the
    previous template):



    FIRST VERION: (works OK)

    <CFQUERY NAME="get_partinfo" DATASOURCE="#request.dsn#" DBTYPE="ODBC">
    SELECT tbl_part_adult.*,
    tbl_adult.assigned_ID, tbl_adult.last_name, tbl_adult.first_name,
    tbl_adult.middle_initial, tbl_adult.ssn, tbl_adult.family_ID AS famID,
    tbl_month.ID AS monthID, tbl_month.month_name, tbl_month.fy_order,
    tbl_school_year.ID AS syID, tbl_school_year.school_year

    FROM tbl_part_adult, tbl_adult, tbl_month, tbl_school_year
    WHERE tbl_part_adult.adult_ID =* tbl_adult.ID
    AND tbl_part_adult.month_ID =* tbl_month.ID
    AND tbl_part_adult.year_id =* tbl_school_year.ID
    AND tbl_adult.ID = <CFQUERYPARAM VALUE="#form.part_ID#"
    CFSQLTYPE="CF_SQL_INTEGER">
    AND tbl_school_year.ID = <CFQUERYPARAM VALUE="#form.year_ID#"
    CFSQLTYPE="CF_SQL_INTEGER">

    ORDER BY tbl_month.fy_order
    </CFQUERY>


    SECOND QUERY: (no results if tbl_part_adult has no records for that adult's
    participation info yet)

    <CFQUERY NAME="get_partinfo" DATASOURCE="#request.dsn#" DBTYPE="ODBC">
    SELECT tbl_part_adult.*,
    tbl_adult.assigned_ID, tbl_adult.last_name, tbl_adult.first_name,
    tbl_adult.middle_initial, tbl_adult.ssn, tbl_adult.family_ID AS famID,
    tbl_month.ID AS monthID, tbl_month.month_name, tbl_month.fy_order,
    tbl_school_year.ID AS syID, tbl_school_year.school_year

    FROM tbl_part_adult

    LEFT OUTER JOIN tbl_adult ON tbl_adult.ID = tbl_part_adult.adult_ID
    LEFT OUTER JOIN tbl_month ON tbl_month.ID = tbl_part_adult.month_ID
    LEFT OUTER JOIN tbl_school_year ON tbl_school_year.ID =
    tbl_part_adult.year_id

    WHERE tbl_adult.ID = <CFQUERYPARAM VALUE="#form.part_ID#"
    CFSQLTYPE="CF_SQL_INTEGER">
    AND tbl_school_year.ID = <CFQUERYPARAM VALUE="#form.year_ID#"
    CFSQLTYPE="CF_SQL_INTEGER">

    ORDER BY tbl_month.fy_order
    </CFQUERY>

    Captain Special Guest

  9. #8

    Default Re: Simple ANSI syntax Outer Join question

    I have a hunch it is because you are essentially asking for your query to
    select rows WHERE tbl_school_year.ID = ="#form.year_ID#" even though this table
    is on the tail end of an OUTER JOIN to tbl_part_adult.

    Phil



    Try changing
    AND tbl_school_year.ID = <CFQUERYPARAM VALUE="#form.year_ID#"
    CFSQLTYPE="CF_SQL_INTEGER">


    to
    AND tbl_part_adult.year_id = <CFQUERYPARAM VALUE="#form.year_ID#"
    CFSQLTYPE="CF_SQL_INTEGER">


    paross1 Guest

  10. #9

    Default Re: Simple ANSI syntax Outer Join question

    Thanks for your continued help.

    I follow your logic on the last try, but unfortunately the results are the
    same: zilch if a participant record has not yet been created. And when I think
    about it, if tbl_part_adult has no records to match the form variables, but
    tbl_adult and tbl_school_year do, it seems that a WHERE clause would need to be
    phrased the way I did it the first time. So, I guess this one's still up in
    the air. Could it be possible that there is an issue fully implementing
    ANSI-92 on Microsoft SQL Server 2000?

    Captain Special Guest

  11. #10

    Default Re: Simple ANSI syntax Outer Join question

    So, what you are saying is that tbl_school_year relates to tbl_part_adult, and
    tbl_part_adult relates to tbl_adult, so how can you have a link between
    tbl_adult and tbl_school_year without an entry in tbl_part_adult?

    Anyway, does this give you anything more than you were geting?

    Phil


    SELECT tbl_part_adult.*,
    tbl_adult.assigned_ID, tbl_adult.last_name, tbl_adult.first_name,
    tbl_adult.middle_initial, tbl_adult.ssn, tbl_adult.family_ID AS famID,
    tbl_month.ID AS monthID, tbl_month.month_name, tbl_month.fy_order,
    tbl_school_year.ID AS syID, tbl_school_year.school_year
    FROM tbl_adult
    LEFT JOIN tbl_part_adult ON tbl_adult.ID = tbl_part_adult.adult_ID
    LEFT JOIN tbl_month ON tbl_month.ID = tbl_part_adult.month_ID
    LEFT JOIN tbl_school_year ON tbl_school_year.ID = tbl_part_adult.year_id
    AND tbl_school_year.ID = <CFQUERYPARAM VALUE="#form.year_ID#"
    CFSQLTYPE="CF_SQL_INTEGER">
    WHERE tbl_adult.ID = <CFQUERYPARAM VALUE="#form.part_ID#"
    CFSQLTYPE="CF_SQL_INTEGER">
    ORDER BY tbl_month.fy_order

    paross1 Guest

  12. #11

    Default Re: Simple ANSI syntax Outer Join question

    D'oh! Looking at your FIRST VERSION it just occurred to me that =* is actually
    a RIGHT (OUTER) JOIN, not LEFT. You may need to tweak the WHERE clause, but is
    this any better?

    Phil



    <CFQUERY NAME="get_partinfo" DATASOURCE="#request.dsn#" DBTYPE="ODBC">
    SELECT tbl_part_adult.*,
    tbl_adult.assigned_ID, tbl_adult.last_name, tbl_adult.first_name,
    tbl_adult.middle_initial, tbl_adult.ssn, tbl_adult.family_ID AS famID,
    tbl_month.ID AS monthID, tbl_month.month_name, tbl_month.fy_order,
    tbl_school_year.ID AS syID, tbl_school_year.school_year
    FROM tbl_part_adult,
    RIGHT JOIN tbl_adult ON tbl_part_adult.adult_ID = tbl_adult.ID
    RIGHT JOIN tbl_month ON tbl_part_adult.month_ID = tbl_month.ID
    RIGHT JOIN tbl_school_year ON tbl_part_adult.year_id = tbl_school_year.ID
    WHERE tbl_adult.ID = <CFQUERYPARAM VALUE="#form.part_ID#"
    CFSQLTYPE="CF_SQL_INTEGER">
    AND tbl_school_year.ID = <CFQUERYPARAM VALUE="#form.year_ID#"
    CFSQLTYPE="CF_SQL_INTEGER">
    ORDER BY tbl_month.fy_order
    </CFQUERY>

    paross1 Guest

  13. #12

    Default Re: Simple ANSI syntax Outer Join question

    Progress! (Not yet perfection, but who's complaining?) I did not know you
    could put an AND in a JOIN. First, let me address the RIGHT OUTER JOIN thing
    you noticed. You are right, that first iteration did have =* but in my
    subsequent ANSI attempts I did change it to LEFT OUTER JOIN purposefully
    (complete with switching the tbl_adult.ID = tbl_part_adult.adult_ID from one
    side to the other) after my first attempt using RIGHT OUTER JOIN didn't work.
    Though the documentation about outer joins I have says the two are logically
    equivalent if the x = y relationship is just reversed to a y = x, I thought I'd
    still give it a try.

    Despite that, I went ahead and re-tried it, unfortunately to no avail.

    However, there was a small improvement in trying to use your second-to-last
    post. In putting the AND statement in the LEFT JOIN, there was one row of NULL
    values returned. It did not pull the adult participant's info from the
    tbl_adult, nor did it pull the month's name, but at least it was a change - all
    previous attempts pulled zero recordcount.

    Given some hope, I tried putting AND on the other condition that had been in
    the where clause, like so:

    RIGHT JOIN tbl_school_year ON tbl_part_adult.year_id = tbl_school_year.ID
    AND tbl_school_year.ID = <CFQUERYPARAM VALUE="#form.year_ID#"
    CFSQLTYPE="CF_SQL_INTEGER">

    This pulled a gazillion records, some with legit data (for other participants)
    and some null rows as well (though I suspect that those come attached to the
    sets of data returned for participants who have some data recorded for some
    months in a fiscal year, but not for all months in that fiscal year. So,
    though you can see I am kind of fumbling around blindly, your suggestions are
    at least giving me some additional things to try, and narrowing down the
    possible causes for the ANSI query not working like the non-ANSI one.

    Captain Special Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139