outer join with explicit criteria rears its ugly head (again)

6 messages Options
Embed this post
Permalink
Jason Gottshall-2

outer join with explicit criteria rears its ugly head (again)

Reply Threaded More More options
Print post
Permalink
Given the following tables:

Book
   book_id
   title
   ...

Book_User (existence of record indicates that user has read book)
   book_id
   user_id

For a given user, I want to retrieve a list of *all* books, and flag the
one's he/she has read. The SQL for this is pretty clear:

SELECT book.*, book_user.*
FROM book
LEFT OUTER JOIN book_user
   ON (    book_user.book_id = book.book_id
       AND book.user_id      = 'givenuser'
   )

And I can display a flag whenever book_user.user_id is not null. But I
can't seem to figure out a clean way of doing this in DBIC. The join
criteria is dynamic, so it can't be hard-coded into the result source.

So far my solution has been to do two separate queries, selecting
everything from Book, and selecting from Book_User for the given user. I
build a quick little hash from the book_user results and just check the
hash as I loop over the books. It certainly works, but I'm wondering if
anybody's figured out a way to do this type of query more directly in DBIC.


_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...
michael reddick

Re: outer join with explicit criteria rears its ugly head (again)

Reply Threaded More More options
Print post
Permalink
The and "book.user_id = 'giveruser'" doesn't have to be in the ON statement does it? You could just put it into the where clause and it should work the same.

_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...
Jason Gottshall-2

Re: outer join with explicit criteria rears its ugly head (again)

Reply Threaded More More options
Print post
Permalink
Jason Gottshall wrote:
> SELECT book.*, book_user.*
> FROM book
> LEFT OUTER JOIN book_user
>   ON (    book_user.book_id = book.book_id
>       AND book.user_id      = 'givenuser'
>   )

michael reddick wrote:
> The and "book.user_id = 'giveruser'" doesn't have to be in the ON
> statement does it? You could just put it into the where clause and it
> should work the same.

Yeah, that's the first thing I tried, but it didn't work (on Oracle,
anyway.) When I move the explicit criteria to the WHERE clause, I seem
to lose the left-outer-ness of the join, and I only get back books for
which the book_user table has a record. I'm stumped. Anyone else?

Jason


_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...
Nickolay Platonov

Re: outer join with explicit criteria rears its ugly head (again)

Reply Threaded More More options
Print post
Permalink
May be smth like:

$c->model('DB::Book')->search({ 'bookuser.user_id' => givenuser},{
   join => 'bookuser'
});

where the 'bookuser' is the relationship defined like:

Book->belongs_to(
  "bookuser",
  "User",
  { id => "user_id" },
  { join_type => "LEFT OUTER" },
);

?

Sorry for "draftness", I just copied samples from my code.

On Tue, Oct 14, 2008 at 8:51 PM, Jason Gottshall <[hidden email]> wrote:
Jason Gottshall wrote:
SELECT book.*, book_user.*
FROM book
LEFT OUTER JOIN book_user
 ON (    book_user.book_id = book.book_id
     AND book.user_id      = 'givenuser'
 )

michael reddick wrote:
The and "book.user_id = 'giveruser'" doesn't have to be in the ON statement does it? You could just put it into the where clause and it should work the same.

Yeah, that's the first thing I tried, but it didn't work (on Oracle, anyway.) When I move the explicit criteria to the WHERE clause, I seem to lose the left-outer-ness of the join, and I only get back books for which the book_user table has a record. I'm stumped. Anyone else?

Jason


_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...
michael reddick

Re: outer join with explicit criteria rears its ugly head (again)

Reply Threaded More More options
Print post
Permalink
In reply to this post by Jason Gottshall-2
On Tue, Oct 14, 2008 at 11:51 AM, Jason Gottshall <[hidden email]> wrote:
Jason Gottshall wrote:
SELECT book.*, book_user.*
FROM book
LEFT OUTER JOIN book_user
 ON (    book_user.book_id = book.book_id
     AND book.user_id      = 'givenuser'
 )

michael reddick wrote:
The and "book.user_id = 'giveruser'" doesn't have to be in the ON statement does it? You could just put it into the where clause and it should work the same.

Yeah, that's the first thing I tried, but it didn't work (on Oracle, anyway.) When I move the explicit criteria to the WHERE clause, I seem to lose the left-outer-ness of the join, and I only get back books for which the book_user table has a record. I'm stumped. Anyone else?

It's not returning all the books because now it's filtering only the ones where book_user has a record for the user like you said. So it does seem like you can only do it with the $user restriction in the ON clause.

I think you can do something like this but it's really ugly:

$c->model('DB::Book')->search({},
    { from => [ {me => 'book' },
        [ { 'book_user' => 'book_user', -join_type => 'left outer'},
          { 'book_user.book_id' => 'me.book_id', 'book_user.user_id' => '$user'}
        ]
    ] } );


michael

_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...
Benjamin Hitz

Re: outer join with explicit criteria rears its ugly head (again)

Reply Threaded More More options
Print post
Permalink
In reply to this post by Nickolay Platonov
Some javascript/style in this post has been disabled (why?)
I am resurrecting this tread...

So, and maybe this is obvious  - can you define a define two relationships to the same table (both, for example,  'belongs_to' or 'has_many' as schema suggests), but with different join_types?

I can't see why not, but I would hate to go down this path and get creamed.

I think then the solution to original problem would be a where clause something like 
"where book.user_id = 'givenuser' or book.user_id is null"

Ben



May be smth like:

$c->model('DB::Book')->search({ 'bookuser.user_id' => givenuser},{
   join => 'bookuser'
});

where the 'bookuser' is the relationship defined like:

Book->belongs_to(
  "bookuser",
  "User",
  { id => "user_id" },
  { join_type => "LEFT OUTER" },
);

?

Sorry for "draftness", I just copied samples from my code.

On Tue, Oct 14, 2008 at 8:51 PM, Jason Gottshall <[hidden email]> wrote:
Jason Gottshall wrote:
SELECT book.*, book_user.*
FROM book
LEFT OUTER JOIN book_user
 ON (    book_user.book_id = book.book_id
     AND book.user_id      = 'givenuser'
 )

michael reddick wrote:
The and "book.user_id = 'giveruser'" doesn't have to be in the ON statement does it? You could just put it into the where clause and it should work the same.

Yeah, that's the first thing I tried, but it didn't work (on Oracle, anyway.) When I move the explicit criteria to the WHERE clause, I seem to lose the left-outer-ness of the join, and I only get back books for which the book_user table has a record. I'm stumped. Anyone else?

Jason

_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...

--
Ben Hitz 
Senior Scientific Programmer ** Saccharomyces Genome Database ** GO Consortium
Stanford University ** [hidden email]




_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...