3 table join

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • gertie2008
    New Member
    • Feb 2008
    • 11

    3 table join

    Hi,

    I've got 3 tables:
    1.) book: BookID, Title
    2.) bookcomment: BookCommentID, BookID, ContactID, Comment
    3.) responsibilityl og: ResponsibilityI D, BookID, ContactID, DataFrom, DateTo


    Relationships:
    book and bookcomment: one to one
    book and responsibilityl og: one to many

    I want a query that returns book.Title and bookcomment.Com ment WHERE BookID=1 AND ContactID=2 regardless if responsibilityl og returns a record,
    AND
    the query must return all the records with fields book.Title, responsibilityl og.DataFrom and responsibilityl og.DateTo WHERE BookID=1 AND ContactID=2 regardless if bookcomment returns a record

    The following query only returns data if there is a record in bookcomment AND responsibilityl og that meet the conditions because of my AND statement, but I don't know how to rectify this. If I use OR in place of AND, I do not get the desired result.

    [code=mysql]
    rs = st.executeQuery ("select b.Title, rl.DateFrom, rl.DateTo, c.Comment from book b left join responsibilityl og rl on b.BookID = rl.BookID left join bookcomment c on c.BookID = b.BookID WHERE rl.ContactID='" + ContactID + "' AND c.ContactID='" + ContactID + "'");
    [/code]
  • code green
    Recognized Expert Top Contributor
    • Mar 2007
    • 1726

    #2
    regardless if bookcomment returns a record
    Then it needs to be LEFT JOIN

    Comment

    • gertie2008
      New Member
      • Feb 2008
      • 11

      #3
      Thanks for your response,

      I changed it to left join, but still:

      The query only returns data if there is a record in bookcomment AND responsibilityl og that meet the conditions. I have data in responsibilityl og table that should be returned, but for that ContactID and BookID, there is no record in the bookcomment table and therefore it doesn't return the data from the responsibilityl og table.

      Comment

      • henryrhenryr
        New Member
        • Jun 2007
        • 103

        #4
        Originally posted by gertie2008
        [code=sql]
        rs = st.executeQuery ("select b.Title, rl.DateFrom, rl.DateTo, c.Comment from book b left join responsibilityl og rl on b.BookID = rl.BookID left join bookcomment c on c.BookID = b.BookID WHERE rl.ContactID='" + ContactID + "' AND c.ContactID='" + ContactID + "'");
        [/code]
        At a glance I think you can work around either:

        1. Input default settings - when you add a book to your DB, always add records for comment and responsibility, but add default/null rows. Then you don't have the problem.

        2. Probably preferable, I think you should be able to use AND (... OR ...)

        [code=sql]
        select b.Title, rl.DateFrom, rl.DateTo, c.Comment
        from book b
        left join responsibilityl og rl on b.BookID = rl.BookID
        left join bookcomment c on c.BookID = b.BookID
        WHERE (rl.ContactID=' "+CONTACTID +"' OR rl.ContactID IS NULL)
        AND (c.ContactID='" +CONTACTID+"' OR c.ContactID IS NULL)
        [/code]

        or perhaps you're looking for this...

        [code=sql]
        ...
        WHERE (rl.ContactID=' "+CONTACTID +"' AND c.ContactID='"+ CONTACTID+"')
        OR (rl.ContactID IS NULL AND c.ContactID IS NULL)
        [/code]

        Haven't tested though... ;)

        Henry
        Last edited by henryrhenryr; Jun 19 '08, 02:36 PM. Reason: added details...

        Comment

        • gertie2008
          New Member
          • Feb 2008
          • 11

          #5
          Thanks for you input Henry, you've given me some ideas to try out. I have tried various options concerning AND OR. The following example comes pretty close to what I want, except that it returns data from the bookcomment table where the ContactID is not equal to the one that I've specified. I suspect it is because of the way that the joins are made:

          [code=mysql]select b.BookID, b.Title, b.Author, rl.DateFrom, rl.DateTo, c.Comment from book b left join responsibilityl og rl on b.BookID = rl.BookID left join bookcomment c on c.BookID = b.BookID WHERE (rl.ContactID=' "+ContactID +"' OR rl.ContactID IS NULL) OR (c.ContactID='" +ContactID+"' AND c.BookID='"+Boo kID+"')[/code]

          I'm basically trying to combine the following 2 queries:
          1.)[code=mysql]"SELECT b.BookID, b.Title, b.Author, rl.DateFrom, rl.DateTo FROM book b LEFT JOIN responsibilityl og rl ON b.BookID=rl.Boo kID WHERE rl.ContactID=" + ContactID + " ORDER BY Title"[/code]
          2.)[code=mysql]"SELECT b.BookID, b.Title, b.Author, c.Comment FROM book b LEFT JOIN bookcomment c ON b.BookID=c.Book ID WHERE c.ContactID=" + ContactID + " ORDER BY Title"[/code]

          Comment

          • code green
            Recognized Expert Top Contributor
            • Mar 2007
            • 1726

            #6
            The following example comes pretty close to what I want, except that it returns data from the bookcomment table where the ContactID is not equal to the one that I've specified. I suspect it is because of the way that the joins are made:
            Maybe your second LEFT JOIN needs to be an INNER JOIN.
            Code:
            INNER JOIN bookcomment c ON c.BookID = b.BookID
            You can try putting WHERE conditions inside the ON clause. Not sure where you are going with this but I mean
            Code:
            JOIN bookcomment c ON (c.BookID = b.BookID AND c.BookID='"+BookID+"')

            Comment

            • gertie2008
              New Member
              • Feb 2008
              • 11

              #7
              Thanks for your help code green ,

              I am one step closer with the following:

              [code=mysql]
              "select b.BookID, b.Title, b.Author, rl.DateFrom, rl.DateTo, c.Comment from book b left join responsibilityl og rl on b.BookID = rl.BookID left join bookcomment c on (b.BookID = c.BookID AND c.ContactID='"+ ContactID+"') WHERE (rl.ContactID=' "+ContactID +"' OR rl.ContactID IS NULL) OR (c.ContactID='" +ContactID+"' AND c.BookID='"+Boo kID+"')"
              [/code]

              Comment

              • coolsti
                Contributor
                • Mar 2008
                • 310

                #8
                I am just glancing at this thread without spending the time to solve the problem, but I do not think it is very difficult to do (maybe I have time later and will repost).

                But here a comment: The Book and Bookcomment table are 1 to 1 and, indeed, could actually be combined to form one database table. Therefore I would do the query by joining these two tables first, and then doing a left join on the Responsibility table.

                In all the examples I have seen so far, you have first joined the Book and Responsibility table, and then joined the Bookcomment table.

                Comment

                • coolsti
                  Contributor
                  • Mar 2008
                  • 310

                  #9
                  Try this, it works for me (although I used different table definitions, so if you get a syntax error with what I show below, you may need to modify to fix it).

                  select b.BookID, b.Title, b.Author, rl.DateFrom, rl.DateTo, c.Comment
                  from book b left join bookcomment c on b.BookID=c.Book ID
                  left join responsibilityl og rl on b.BookID=rl.Boo kID
                  having b.BookID=1 and
                  ((c.ContactID=2 or c.ContactID is NULL) and
                  (rl.ContactID=2 or rl.ContactID is NULL))

                  First try this without the having clause. You will see that you get a join of all possibilities: all book ID's and their associated rows in the two other tables. The HAVING clause is then used to filter out the ones you don't wish. The filter is of course over the book ID, and then two other conditions:

                  1) either the bookcomment ContactID is the value you are looking for or it is NULL (the row is not present for this book in the bookcomment table)

                  2) either the responsibilityl og ContactID is the value you are looking for, or is NULL (the row is not present for this book in the responsibilityl og table.

                  Try this. I think it is what you need. Oh, of course you must substitute the "1" and the "2" in my example for whatever variables you are using.

                  Comment

                  Working...