HQL - can i join when the association is backwards? - hql

I have:
class A
{
B b;
}
class B
{
}
I know i can do this:
from A a
join a.b b
but what I need to do is this (pseudo-HQL, it doesn't parse, hence this post):
from B b
left outer join A a on a.b = b
I get "Path expected for join!" :(
I want a complete list of Bs joined onto any As, if they exist. Is this possible?
I can't use a right join because SQLite doesn't support them grrrrr
What can I do to solve this?
Thanks

Is there a reason you can't have
class B {
#ManyToMany
A a;
}
?

HQL have "with" keyword instead of on (joins are fundamentally different then in sql)
try :
from B b, A a
left join a.b ab with ab = b
or simply:
from B b, A a where a.b = b

Related

Trying to migrate from Oracle to PostgreSQL

SELECT b.SERVICENAME,
a.PARAMETERNAME,
a.PARAMETERVALUE
FROM serviceParameter a,
subscriberService b,
serviceName c
WHERE a.SUBSCRIBERKEY (+) = 15677889
AND b.SUBSCRIBERKEY = 15677889
AND b.SERVICENAME = a.SERVICENAME(+)
AND c.SERVICENAME = b.SERVICENAME
AND c.MULTIINSTANCE = '0'
ORDER BY a.SERVICENAME;
How can I migrate the above code to PostgresSQL?
You have to translate it along these lines:
SELECT ...
FROM a, b
WHERE a.x = b.y(+)
AND a.p = 42
AND b.q(+) = 'foo';
will become:
SELECT ...
FROM a LEFT OUTER JOIN b
ON a.x = b.y
AND b.q = 'foo'
WHERE a.p = 42;
That is:
The side with the (+) becomes the right side of a LEFT OUTER JOIN (or, equivalently, the left side of a RIGHT OUTER JOIN).
All the WHERE conditions that contain a (+) lose that adornment and go into the join condition.
It is easy to translate Oracle's join syntax to standard conforming syntax because the latter is more powerful (and easier to read to boot).

How to perform LINQ left outer join using method syntax?

Microsoft has this help page for performing a left outer join, however it's in linq query syntax. What's the equivalent to this, using method syntax?
http://msdn.microsoft.com/en-us/library/bb397895.aspx
For example, I have two enumerables:
class TA {string Name{get;}}
class TB {string Name{get;}}
Enumerable<TA> A;
Enumerable<TB> B;
The result I want is this:
var joined =
A.Select(a => new
{ left = a,
right = B.FirstOrDefault(b => b.Name == a.Name)
});
This gives me what I need with just select and (effectively) a nested select. Perhaps this isn't an actual left outer join...
I've used something like
var q = (from a in db.Item1Set
from b in db.Item2Set.Where(i2 => i2.Item1Id == a.Id).DefaultIfEmpty());

get things out of bag in pig

In the pig example:
A = LOAD 'student.txt' AS (name:chararray, term:chararray, gpa:float);
DUMP A;
(John,fl,3.9F)
(John,wt,3.7F)
(John,sp,4.0F)
(John,sm,3.8F)
(Mary,fl,3.8F)
(Mary,wt,3.9F)
(Mary,sp,4.0F)
(Mary,sm,4.0F)
B = GROUP A BY name;
DUMP B;
(John,{(John,fl,3.9F),(John,wt,3.7F),(John,sp,4.0F),(John,sm,3.8F)})
(Mary,{(Mary,fl,3.8F),(Mary,wt,3.9F),(Mary,sp,4.0F),(Mary,sm,4.0F)})
C = FOREACH B GENERATE A.name, AVG(A.gpa);
DUMP C;
({(John),(John),(John),(John)},3.850000023841858)
({(Mary),(Mary),(Mary),(Mary)},3.925000011920929)
The last output A.name is a bag. How can I get things out of bag:
(John, 3.850000023841858)
(Mary, 3.925000011920929)
GROUP creats a magical item called group, which is what you grouped on. This is made for exactly this purpose.
B = GROUP A BY name;
C = FOREACH B GENERATE group AS name, AVG(A.gpa);
Check out DESCRIBE B;, you'll see that group is in there. It is a single value that represents what was in the BY ... part of the GROUP.

Multiple Left Outer Joins with Collections and EF4

I have a Linq statement using EF4
var q = from a in FunctionA
from b in FunctionB.Where(a=>a.Id== b.Id).DefaultIfEmpty()
from c in FunctionC.Where(c=>c.Id== b.Id).DefaultIfEmpty()
select a;
where FunctionA,FunctionB and FunctionC returns Collections.
For some data conditions, i am getting a null exception, since the value of b in "from b in FunctionB.Where(a=> a.Id== b.Id).DefaultIfEmpty()" is null sometimes and then the statement "from c in FunctionC.Where(c=>c.Id== b.Id).DefaultIfEmpty()" blows up since b is null.
What would be correct way to do an outer join here ? please help !
Thanks !
Your Where syntax looks incorrect and I think you are actually using linq-to-objects, but all you need to do is add a condition to check Where b is not null
Edit - Based on your comments you want to do this
var q = from a in FunctionA
from b in FunctionB.Where(x => a.Id == x.Id).DefaultIfEmpty()
from c in FunctionC.Where(x => b != null && b.Id== x.Id).DefaultIfEmpty()
select a;

LINQ query complex join problem

So I was trying to convert a SQL into LINQ query
the logic is:
JOIN SalesPeriod SP1
ON
SP1.SalesPeriodId = SE1.SalesPeriodId AND SP1.SalePeriodId = .....(XML stuff)
but it keeps complaining the types on both sides of equals statement don't match
Any ideas?
Note: I declared b and d because it doesn't accept anonymous type members
and I tested two equal conditions separately and they both work
thanks
join SP1 in fentities.SalesPeriods
on new { SE1.SalesPeriodId, b = XDocument.Load(MI.Body).Element("ns:Transfer").Element("ns:ReceivedBy").Element("ns:Id").FirstNode.ToString() }
equals new { SP1.SalesPeriodId, d = SP1.SalesPeriodId.ToString() }
Simple, they're not the same (compatible) types. The first key has a SalesPeriodId of type whatever, and b of type string. The second key has a SalesPeriodId of type whatever (probably the same as the first's), and d of type string. You can't compare these to eachother. It must have the same properties of the same types declared in the same order. Just pick one of the names b or d and use that name.
...
join SP1 in fentities.SalesPeriods
on new { SE1.SalesPeriodId, b = XDocument.Load(MI.Body).Element("ns:Transfer").Element("ns:ReceivedBy").Element("ns:Id").FirstNode.ToString() }
equals new { SP1.SalesPeriodId, b = SP1.SalesPeriodId.ToString() }
Your two anonymous types do not match, b & d to be specific.. try aligning the signatures..
join SP1 in fentities.SalesPeriods
on new { SE1.SalesPeriodId, b = XDocument.Load(MI.Body).Element("ns:Transfer").Element("ns:ReceivedBy").Element("ns:Id").FirstNode.ToString() }
equals new { SP1.SalesPeriodId, b = SP1.SalesPeriodId.ToString() }
In that example both anonymous objects will have the same property definitions (SalesPeriodId and b)
Don't stuck on putting complete join condition into 'ON' clause. Split condition on two parts, put one of them into 'ON' clause and another into 'WHERE' clause.
join SP1 in fentities.SalesPeriods
on SE1.SalesPeriodId equals SP1.SalesPeriodId
where XDocument.Load(MI.Body).Element("ns:Transfer").Element("ns:ReceivedBy").Element("ns:Id").FirstNode.ToString() == SP1.SalesPeriodId.ToString()

Resources