-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Group by problem
PostPosted: Mon Dec 08, 2003 6:05 am 
Newbie

Joined: Thu Dec 04, 2003 5:53 am
Posts: 11
Location: Toulouse, France
Hello. Using Hibernate 2.0.3. This follows on from topic http://forum.hibernate.org/viewtopic.php?t=925550, and from the FAQ on ordering by the size of a collection http://www.hibernate.org/118.html#A6.

The problem concerns the group by clause.

The examples below assume a structure where country has a one-to-many parent-to-child relationship with author, and author has a one-to-many parent-to-child relationship with book.

Problem 1 and solution 1 are as per the previous topic. Problem 2 and solution 2 are apparently new on this forum.

Problem 1. Select all authors having one or more books.
HQL:
Code:
SELECT author FROM tests.Author author
JOIN author.books book
GROUP BY author
HAVING count(book)>0

Generated SQL:
Code:
select author0_.authorId as authorId, author0_.name as name, author0_.countryId as countryId from Author author0_
inner join Book books1_ on author0_.authorId=books1_.authorId
group by author0_.authorId
having (count(books1_.bookId)>0 )

Error:
Could not execute query: Column 'author0_.name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause

Solution 1. Explicitly group by the author's attributes.
HQL:
Code:
SELECT author FROM tests.Author author
JOIN author.books book
GROUP BY author, author.country, author.name
HAVING count(book)>0

Generated SQL:
Code:
select author0_.authorId as authorId, author0_.name as name, author0_.countryId as countryId from Author author0_
inner join Book books1_ on author0_.authorId=books1_.authorId
group by  author0_.authorId , author0_.countryId , author0_.name
having (count(books1_.bookId)>0 )

Error: none.

Problem 2: now we add an inner join from Author to Country (e.g. select all authors from countries starting with S having one or more books).
HQL:
Code:
SELECT author FROM tests.Author author
JOIN author.books book
JOIN author.country country
WHERE country.name like ?
GROUP BY author, author.country, author.name
HAVING count(book)>0

Generated SQL:
Code:
select author0_.authorId as authorId, author0_.name as name, author0_.countryId as countryId from Author author0_
inner join Book books1_ on author0_.authorId=books1_.authorId
inner join Country country2_ on author0_.countryId=country2_.countryId where (country2_.name like ? )
group by  author0_.authorId , country2_.countryId , author0_.name
having (count(books1_.bookId)>0 )

Error:
Could not execute query: Column 'author0_.countryId' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Note that adding country as an inner join caused the explicit reference to author.country to be replaced by country2_.countryId, rather than author_0.countryId, thus causing the failure.

Solution 2 (clumsy) - replace the inner join by an exists clause
HQL:
Code:
SELECT author FROM tests.Author author
JOIN author.books book
WHERE EXISTS (SELECT country FROM tests.Country country
WHERE author.country=country
AND country.name like ?)
GROUP BY author, author.country, author.name
HAVING count(book)>0

Generated SQL:
Code:
select author0_.authorId as authorId, author0_.name as name, author0_.countryId as countryId from Author author0_
inner join Book books1_ on author0_.authorId=books1_.authorId
where (EXISTS(select country2_.countryId from Country  country2_ where (author0_.countryId=country2_.countryId )AND(country2_.name like ? )))
group by  author0_.authorId , author0_.countryId , author0_.name
having
(count(books1_.bookId)>0 )


No errors, but perhaps there is a more elegant solution to this?

Best regards,
Assaf


Top
 Profile  
 
 Post subject: Re: Group by problem
PostPosted: Wed Dec 10, 2003 5:20 am 
Newbie

Joined: Thu Dec 04, 2003 5:53 am
Posts: 11
Location: Toulouse, France
Note: if you can make do with session.iterate or query.iterate instead of session.find or query.list, you can avoid the problems above, since the iterate methods only select the id, and fill in the object's other attributes at a later stage.

- Assaf


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.