Multi-table SQL select statement & cfoutput syntax











up vote
2
down vote

favorite












I teach web design to high school students. Recently I introduced them to dynamic web design with SQL and coldfusion. I have been keeping it rather simple, but I do want to show them a complex SQL statement and a complex cfoutput. Unfortunately I have made the problem too complex for me to figure out! Here is a pic of my database structure:



I am trying to output a list of students enrolled in each class along with the session the class is offered, and the teacher who teaches the class. Here is an example of what I am trying to output


Robotics

Session 1

Mr. Smith



  1. Fry, Karen

  2. Johnson, Johnny

  3. Turner, Haley



And then I want to output the information for the next class, and so on.



Here is the cfoutput code I am using:



<cfoutput query="getRoster" group="staff">
#firstname# #lastname#<br>
#className#<br>
#sessionNumber#<br>
#title# #lastname#<br>
<cfoutput>
`<ol><li>#lastname#, #firstname#</li></ol>`
</cfoutput>
</cfoutput>









share|improve this question
























  • What version and flavor of SQL and what version of CF?
    – Shawn
    Nov 12 at 18:47















up vote
2
down vote

favorite












I teach web design to high school students. Recently I introduced them to dynamic web design with SQL and coldfusion. I have been keeping it rather simple, but I do want to show them a complex SQL statement and a complex cfoutput. Unfortunately I have made the problem too complex for me to figure out! Here is a pic of my database structure:



I am trying to output a list of students enrolled in each class along with the session the class is offered, and the teacher who teaches the class. Here is an example of what I am trying to output


Robotics

Session 1

Mr. Smith



  1. Fry, Karen

  2. Johnson, Johnny

  3. Turner, Haley



And then I want to output the information for the next class, and so on.



Here is the cfoutput code I am using:



<cfoutput query="getRoster" group="staff">
#firstname# #lastname#<br>
#className#<br>
#sessionNumber#<br>
#title# #lastname#<br>
<cfoutput>
`<ol><li>#lastname#, #firstname#</li></ol>`
</cfoutput>
</cfoutput>









share|improve this question
























  • What version and flavor of SQL and what version of CF?
    – Shawn
    Nov 12 at 18:47













up vote
2
down vote

favorite









up vote
2
down vote

favorite











I teach web design to high school students. Recently I introduced them to dynamic web design with SQL and coldfusion. I have been keeping it rather simple, but I do want to show them a complex SQL statement and a complex cfoutput. Unfortunately I have made the problem too complex for me to figure out! Here is a pic of my database structure:



I am trying to output a list of students enrolled in each class along with the session the class is offered, and the teacher who teaches the class. Here is an example of what I am trying to output


Robotics

Session 1

Mr. Smith



  1. Fry, Karen

  2. Johnson, Johnny

  3. Turner, Haley



And then I want to output the information for the next class, and so on.



Here is the cfoutput code I am using:



<cfoutput query="getRoster" group="staff">
#firstname# #lastname#<br>
#className#<br>
#sessionNumber#<br>
#title# #lastname#<br>
<cfoutput>
`<ol><li>#lastname#, #firstname#</li></ol>`
</cfoutput>
</cfoutput>









share|improve this question















I teach web design to high school students. Recently I introduced them to dynamic web design with SQL and coldfusion. I have been keeping it rather simple, but I do want to show them a complex SQL statement and a complex cfoutput. Unfortunately I have made the problem too complex for me to figure out! Here is a pic of my database structure:



I am trying to output a list of students enrolled in each class along with the session the class is offered, and the teacher who teaches the class. Here is an example of what I am trying to output


Robotics

Session 1

Mr. Smith



  1. Fry, Karen

  2. Johnson, Johnny

  3. Turner, Haley



And then I want to output the information for the next class, and so on.



Here is the cfoutput code I am using:



<cfoutput query="getRoster" group="staff">
#firstname# #lastname#<br>
#className#<br>
#sessionNumber#<br>
#title# #lastname#<br>
<cfoutput>
`<ol><li>#lastname#, #firstname#</li></ol>`
</cfoutput>
</cfoutput>






sql coldfusion






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 at 6:47









Sanal Sunny

6648




6648










asked Nov 12 at 2:28









J Aument

152




152












  • What version and flavor of SQL and what version of CF?
    – Shawn
    Nov 12 at 18:47


















  • What version and flavor of SQL and what version of CF?
    – Shawn
    Nov 12 at 18:47
















What version and flavor of SQL and what version of CF?
– Shawn
Nov 12 at 18:47




What version and flavor of SQL and what version of CF?
– Shawn
Nov 12 at 18:47












1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










Assuming your query returns the correct data already, you're close. The query just needs a few changes:




  1. Since the "firstName" and "lastName" columns exist in multiple tables, the query must apply a different column alias to each one, ie SELECT student.lastName AS StudentLastName, ..... Otherwise, CF won't know which value to output when it sees #firstName# and #lastName#.


  2. The cfoutput should probably "group" by className, instead staff. Otherwise, it won't display all of the class names if the same staff member is assigned to multiple classes.


  3. CFOutput "group" requires query results to be sorted. Be sure the query is ORDER(ed) BY className (or whatever column you're grouping by) or the cfoutput won't display correctly.


  4. In order to generate list numbers, the <ol> element belongs outside the inner <cfoutput> loop.



Query:



SELECT
c.className
, c.sessionNumber
, s.LastName AS StaffLastName
, s.FirstName AS StaffFirstName
, st.LastName AS StudentLastName
, st.FirstName AS StudentFirstName
FROM class c
INNER JOIN staff s ON s.id = c.staff
INNER JOIN studentOld st ON st.class1 = c.id
OR st.class2 = c.id
OR st.class3 = c.id
OR st.class4 = c.id
ORDER BY c.className, st.LastName, st.FirstName


CF



<cfoutput query="getRoster" group="className">
#StaffTitle# #StaffLastName# #StaffLastName#<br>
#className#<br>
#sessionNumber#<br>
<ol>
<cfoutput>
<li>#StudentLastName#, #StudentFirstName#</li>
</cfoutput>
</ol>
</cfoutput>


Improvements



That said, if possible I'd restructure the student table as that's not the typical way to represent the many-to-many relationship that exists between student and class. (Best to reinforce good database structure habits now!) A cleaner and more normalized approach is to remove the classX columns from the student table. Then store those relationships in a separate table - as individual rows - rather than columns. That allows the flexibility for as many, or as few, enrollments as needed.



CREATE TABLE student (
id int
, lastName varchar(100)
, firstName varchar(50)
)

-- stores each combination of student + class as a separate row
CREATE TABLE studentClass (
student int
, class int
)


Then you can get rid of all the OR statements and retrieve the classes and enrolled students, with a slightly cleaner JOIN:



SELECT ...
FROM class c
INNER JOIN staff s ON s.id = c.staff
INNER JOIN studentClass sc ON sc.class = c.id
INNER JOIN student st ON st.id = sc.student
ORDER BY ....





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53255276%2fmulti-table-sql-select-statement-cfoutput-syntax%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote



    accepted










    Assuming your query returns the correct data already, you're close. The query just needs a few changes:




    1. Since the "firstName" and "lastName" columns exist in multiple tables, the query must apply a different column alias to each one, ie SELECT student.lastName AS StudentLastName, ..... Otherwise, CF won't know which value to output when it sees #firstName# and #lastName#.


    2. The cfoutput should probably "group" by className, instead staff. Otherwise, it won't display all of the class names if the same staff member is assigned to multiple classes.


    3. CFOutput "group" requires query results to be sorted. Be sure the query is ORDER(ed) BY className (or whatever column you're grouping by) or the cfoutput won't display correctly.


    4. In order to generate list numbers, the <ol> element belongs outside the inner <cfoutput> loop.



    Query:



    SELECT
    c.className
    , c.sessionNumber
    , s.LastName AS StaffLastName
    , s.FirstName AS StaffFirstName
    , st.LastName AS StudentLastName
    , st.FirstName AS StudentFirstName
    FROM class c
    INNER JOIN staff s ON s.id = c.staff
    INNER JOIN studentOld st ON st.class1 = c.id
    OR st.class2 = c.id
    OR st.class3 = c.id
    OR st.class4 = c.id
    ORDER BY c.className, st.LastName, st.FirstName


    CF



    <cfoutput query="getRoster" group="className">
    #StaffTitle# #StaffLastName# #StaffLastName#<br>
    #className#<br>
    #sessionNumber#<br>
    <ol>
    <cfoutput>
    <li>#StudentLastName#, #StudentFirstName#</li>
    </cfoutput>
    </ol>
    </cfoutput>


    Improvements



    That said, if possible I'd restructure the student table as that's not the typical way to represent the many-to-many relationship that exists between student and class. (Best to reinforce good database structure habits now!) A cleaner and more normalized approach is to remove the classX columns from the student table. Then store those relationships in a separate table - as individual rows - rather than columns. That allows the flexibility for as many, or as few, enrollments as needed.



    CREATE TABLE student (
    id int
    , lastName varchar(100)
    , firstName varchar(50)
    )

    -- stores each combination of student + class as a separate row
    CREATE TABLE studentClass (
    student int
    , class int
    )


    Then you can get rid of all the OR statements and retrieve the classes and enrolled students, with a slightly cleaner JOIN:



    SELECT ...
    FROM class c
    INNER JOIN staff s ON s.id = c.staff
    INNER JOIN studentClass sc ON sc.class = c.id
    INNER JOIN student st ON st.id = sc.student
    ORDER BY ....





    share|improve this answer



























      up vote
      2
      down vote



      accepted










      Assuming your query returns the correct data already, you're close. The query just needs a few changes:




      1. Since the "firstName" and "lastName" columns exist in multiple tables, the query must apply a different column alias to each one, ie SELECT student.lastName AS StudentLastName, ..... Otherwise, CF won't know which value to output when it sees #firstName# and #lastName#.


      2. The cfoutput should probably "group" by className, instead staff. Otherwise, it won't display all of the class names if the same staff member is assigned to multiple classes.


      3. CFOutput "group" requires query results to be sorted. Be sure the query is ORDER(ed) BY className (or whatever column you're grouping by) or the cfoutput won't display correctly.


      4. In order to generate list numbers, the <ol> element belongs outside the inner <cfoutput> loop.



      Query:



      SELECT
      c.className
      , c.sessionNumber
      , s.LastName AS StaffLastName
      , s.FirstName AS StaffFirstName
      , st.LastName AS StudentLastName
      , st.FirstName AS StudentFirstName
      FROM class c
      INNER JOIN staff s ON s.id = c.staff
      INNER JOIN studentOld st ON st.class1 = c.id
      OR st.class2 = c.id
      OR st.class3 = c.id
      OR st.class4 = c.id
      ORDER BY c.className, st.LastName, st.FirstName


      CF



      <cfoutput query="getRoster" group="className">
      #StaffTitle# #StaffLastName# #StaffLastName#<br>
      #className#<br>
      #sessionNumber#<br>
      <ol>
      <cfoutput>
      <li>#StudentLastName#, #StudentFirstName#</li>
      </cfoutput>
      </ol>
      </cfoutput>


      Improvements



      That said, if possible I'd restructure the student table as that's not the typical way to represent the many-to-many relationship that exists between student and class. (Best to reinforce good database structure habits now!) A cleaner and more normalized approach is to remove the classX columns from the student table. Then store those relationships in a separate table - as individual rows - rather than columns. That allows the flexibility for as many, or as few, enrollments as needed.



      CREATE TABLE student (
      id int
      , lastName varchar(100)
      , firstName varchar(50)
      )

      -- stores each combination of student + class as a separate row
      CREATE TABLE studentClass (
      student int
      , class int
      )


      Then you can get rid of all the OR statements and retrieve the classes and enrolled students, with a slightly cleaner JOIN:



      SELECT ...
      FROM class c
      INNER JOIN staff s ON s.id = c.staff
      INNER JOIN studentClass sc ON sc.class = c.id
      INNER JOIN student st ON st.id = sc.student
      ORDER BY ....





      share|improve this answer

























        up vote
        2
        down vote



        accepted







        up vote
        2
        down vote



        accepted






        Assuming your query returns the correct data already, you're close. The query just needs a few changes:




        1. Since the "firstName" and "lastName" columns exist in multiple tables, the query must apply a different column alias to each one, ie SELECT student.lastName AS StudentLastName, ..... Otherwise, CF won't know which value to output when it sees #firstName# and #lastName#.


        2. The cfoutput should probably "group" by className, instead staff. Otherwise, it won't display all of the class names if the same staff member is assigned to multiple classes.


        3. CFOutput "group" requires query results to be sorted. Be sure the query is ORDER(ed) BY className (or whatever column you're grouping by) or the cfoutput won't display correctly.


        4. In order to generate list numbers, the <ol> element belongs outside the inner <cfoutput> loop.



        Query:



        SELECT
        c.className
        , c.sessionNumber
        , s.LastName AS StaffLastName
        , s.FirstName AS StaffFirstName
        , st.LastName AS StudentLastName
        , st.FirstName AS StudentFirstName
        FROM class c
        INNER JOIN staff s ON s.id = c.staff
        INNER JOIN studentOld st ON st.class1 = c.id
        OR st.class2 = c.id
        OR st.class3 = c.id
        OR st.class4 = c.id
        ORDER BY c.className, st.LastName, st.FirstName


        CF



        <cfoutput query="getRoster" group="className">
        #StaffTitle# #StaffLastName# #StaffLastName#<br>
        #className#<br>
        #sessionNumber#<br>
        <ol>
        <cfoutput>
        <li>#StudentLastName#, #StudentFirstName#</li>
        </cfoutput>
        </ol>
        </cfoutput>


        Improvements



        That said, if possible I'd restructure the student table as that's not the typical way to represent the many-to-many relationship that exists between student and class. (Best to reinforce good database structure habits now!) A cleaner and more normalized approach is to remove the classX columns from the student table. Then store those relationships in a separate table - as individual rows - rather than columns. That allows the flexibility for as many, or as few, enrollments as needed.



        CREATE TABLE student (
        id int
        , lastName varchar(100)
        , firstName varchar(50)
        )

        -- stores each combination of student + class as a separate row
        CREATE TABLE studentClass (
        student int
        , class int
        )


        Then you can get rid of all the OR statements and retrieve the classes and enrolled students, with a slightly cleaner JOIN:



        SELECT ...
        FROM class c
        INNER JOIN staff s ON s.id = c.staff
        INNER JOIN studentClass sc ON sc.class = c.id
        INNER JOIN student st ON st.id = sc.student
        ORDER BY ....





        share|improve this answer














        Assuming your query returns the correct data already, you're close. The query just needs a few changes:




        1. Since the "firstName" and "lastName" columns exist in multiple tables, the query must apply a different column alias to each one, ie SELECT student.lastName AS StudentLastName, ..... Otherwise, CF won't know which value to output when it sees #firstName# and #lastName#.


        2. The cfoutput should probably "group" by className, instead staff. Otherwise, it won't display all of the class names if the same staff member is assigned to multiple classes.


        3. CFOutput "group" requires query results to be sorted. Be sure the query is ORDER(ed) BY className (or whatever column you're grouping by) or the cfoutput won't display correctly.


        4. In order to generate list numbers, the <ol> element belongs outside the inner <cfoutput> loop.



        Query:



        SELECT
        c.className
        , c.sessionNumber
        , s.LastName AS StaffLastName
        , s.FirstName AS StaffFirstName
        , st.LastName AS StudentLastName
        , st.FirstName AS StudentFirstName
        FROM class c
        INNER JOIN staff s ON s.id = c.staff
        INNER JOIN studentOld st ON st.class1 = c.id
        OR st.class2 = c.id
        OR st.class3 = c.id
        OR st.class4 = c.id
        ORDER BY c.className, st.LastName, st.FirstName


        CF



        <cfoutput query="getRoster" group="className">
        #StaffTitle# #StaffLastName# #StaffLastName#<br>
        #className#<br>
        #sessionNumber#<br>
        <ol>
        <cfoutput>
        <li>#StudentLastName#, #StudentFirstName#</li>
        </cfoutput>
        </ol>
        </cfoutput>


        Improvements



        That said, if possible I'd restructure the student table as that's not the typical way to represent the many-to-many relationship that exists between student and class. (Best to reinforce good database structure habits now!) A cleaner and more normalized approach is to remove the classX columns from the student table. Then store those relationships in a separate table - as individual rows - rather than columns. That allows the flexibility for as many, or as few, enrollments as needed.



        CREATE TABLE student (
        id int
        , lastName varchar(100)
        , firstName varchar(50)
        )

        -- stores each combination of student + class as a separate row
        CREATE TABLE studentClass (
        student int
        , class int
        )


        Then you can get rid of all the OR statements and retrieve the classes and enrolled students, with a slightly cleaner JOIN:



        SELECT ...
        FROM class c
        INNER JOIN staff s ON s.id = c.staff
        INNER JOIN studentClass sc ON sc.class = c.id
        INNER JOIN student st ON st.id = sc.student
        ORDER BY ....






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 12 at 17:00

























        answered Nov 12 at 6:40









        Ageax

        1,993521




        1,993521






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53255276%2fmulti-table-sql-select-statement-cfoutput-syntax%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Bressuire

            Vorschmack

            Quarantine