Grails left outer join query HQL or criteria challenge - grails

I am a newbie to hql and tried out several combinations that i could find but i seem unable to construct the correct HQL query for a left join.
I have the following domain model:
class Company {
static hasMany = [employees: Employee]
}
class Employee {
static belongsTo = [
Company
]
}
So a employee does not know anything about the companies. Now i would like to create a hql query that gives met the employees without a company. In sql i have successfully created the query using a left join but i seem not to be able to create a criteria or hql query that gives me a correct result.
Any a clue or some tips on how i could achieve the result?

Here you go, this works:
Employee.executeQuery("""
Select e
from Employee e
where e not in (Select ce from Company c left join c.employees ce)
""")

Related

Unusual Joins SQL

I am having to convert code written by a former employee to work in a new database. In doing so I came across some joins I have never seen and do not fully understand how they work or if there is a need for them to be done in this fashion.
The joins look like this:
From Table A
Join(Table B
Join Table C
on B.Field1 = C.Field1)
On A.Field1 = B.Field1
Does this code function differently from something like this:
From Table A
Join Table B
On A.Field1 = B.Field1
Join Table C
On B.Field1 = C.Field1
If there is a difference please explain the purpose of the first set of code.
All of this is done in SQL Server 2012. Thanks in advance for any help you can provide.
I could create a temp table and then join that. But why use up the cycles\RAM on additional storage and indexes if I can just do it on the fly?
I ran across this scenario today in SSRS - a user wanted to see all the Individuals granted access through an AD group. The user was using a cursor and some temp tables to get the users out of AD and then joining the user to each SSRS object (Folders, reports, linked reports) associated with the AD group. I simplified the whole thing with Cross Apply and a sub query.
GroupMembers table
GroupName
UserID
UserName
AccountType
AccountTypeDesc
SSRSOjbects_Permissions table
Path
PathType
RoleName
RoleDesc
Name (AD group name)
The query needs to return each individual in an AD group associated with each report. Basically a Cartesian product of users to reports within a subset of data. The easiest way to do this looks like this:
select
G.GroupName, G.UserID, G.Name, G.AccountType, G.AccountTypeDesc,
[Path], PathType, RoleName, RoleDesc
from
GroupMembers G
cross apply
(select
[Path], PathType, RoleName, RoleDesc
from
SSRSOjbects_Permissions
where
Name = G.GroupName) S;
You could achieve this with a temp table and some outer joins, but why waste system resources?
I saw this kind of joins - it's MS Access style for handling multi-table joins. In MS Access you need to nest each subsequent join statement into its level brackets. So, for example this T-SQL join:
SELECT a.columna, b.columnb, c.columnc
FROM tablea AS a
LEFT JOIN tableb AS b ON a.id = b.id
LEFT JOIN tablec AS c ON a.id = c.id
you should convert to this:
SELECT a.columna, b.columnb, c.columnc
FROM ((tablea AS a) LEFT JOIN tableb AS b ON a.id = b.id) LEFT JOIN tablec AS c ON a.id = c.id
So, yes, I believe you are right in your assumption

Grails query map where object1 hasMany object2

I want to do a query like this:
I have a Tale that hasMany secondaryTags
and the query I am trying to do is the following:
def query = 'select new map(title as title,
mainTag as mainTag,
secondaryTags as secondaryTags) from Tale order by rand()';
def result = Tale.executeQuery(query, [max: 3])
But as secondaryTags is a Collection of Tag it doesn't work. Does anyone know how I do this?
Thanks a lot in advance!
A join is required to fetch the associations. Try this query, it should work:
select new map( tale.title as title,
tale.mainTag as mainTag,
sts as secondaryTags )
from Tale as tale
inner join fetch tale.secondaryTags as sts
order by rand()
since you are seeking a map. Otherwise
select tale from Tale as tale
inner join fetch tale.secondaryTags
order by rand()
should be sufficient to get whatever you need from one query. Also note that inner join fetch is used, which means the above query will eagerly fetch the association secondaryTags from tale in the same query, instead of firing another query to get the association if tale.secondaryTags is issued. To witness the fact, enable logging (logSql = true) in DataSource.groovy and check the behavior of the aforementioned principle.

Hive query, efficient non equi join?

I have two tables.
tableOne contains
userid
gameid
starttimestamp
endtimestamp
tableTwo contains
userid
actiontimestamp
someaction
Given the userid and gameid, I want to see how many actions there were in each game id. Given only equi join is allowed, what's a efficient way to join them together?
Most of my crossjoin and filter attempts ended up mapper and reducer getting stuck at 100%.
You could handle all your "theta join" (non-equijoin) conditions in the WHERE clause. Like this:
SELECT * FROM OrderLineItem li LEFT OUTER JOIN ProductPrice p ON p.ProductID = li.ProductID
WHERE (p.StartDate IS NULL AND p.EndDate IS NULL)
OR li.OrderDate BETWEEN p.StartDate AND p.EndDate;
Of course, this example assumes StartDate and EndDate are both non-nullable columns of ProductPrice.
Non equi joins are not available in Hive.
For optimizing equi joins you can try the following.
1.You can implement Buckets in Hive.
2.Read this facebook article also.
3.Do you have more than one job ?.if yes ,enable parallel execution in hive.
if your jobs are indepenent they run parallel.
4.If one of the tables is small ,use distributed cache with add file option in hive.

Criteria to get all domains with collection less than property

Given the following domain class:
class Game {
Integer maxUsers
static hasMany = [users: User]
}
Using the Criteria API, what should I do to get all domains with the number of users less than maxUsers property?
I don't think it's possible to do with Criteria api, as Hibernate Criteria don't support HAVING clause. There is an open JIRA issue for that, you can try patches submitted there.
An alternative would be to use HQL:
def results = Game.findAll("from Game where id in (select g.id from Game g join g.users u group by g.id, g.maxUsers having count(u) < g.maxUsers)")

How to access relationship table when doing executeQuery in Grails?

Is it possible to access the relationship table when doing HQL statement?
As an example, I have 3 tables: account, commitment, account_commitment. It was generated using these domains:
class Account {
static hasMany = [ commits : Commitment ]
String name
}
class Commitment {
static hasMany = [ actors : Account ]
String description
}
My final and actual SQL query is something like this:
SELECT
b.id,
account_name,
d.nid,
d.title
FROM
account_commitment a, // is this available in HQL?
account b,
commitment c,
content_type_act d
where
d.nid = 3332
and a.account_id = b.id
and a.act_id = c.id
and c.act_id = d.nid
I believe HQL only allows valid class domains. Since the relationship table is automatically generated, is this possible in HQL?
Thanks.
No, HQL only works with mapped classes. If you want to run SQL queries just use groovy.sql.Sql. But if you only want to access the intermediate table to join the other two, that's unnecessary since HQL knows about the relationships between tables already.

Resources