How to write an inner join query to retrieve all records of three tables in Hibernate? - spring

I want to retrieve all records from 3 tables: Personal_Info, Address, and Fitness. I have primary key as CandidateID in Personal_Info table and foreign key as CandidateID in Address table and UserID in Fitness table.
I have written inner query as below which seems to be incorrect as I am not getting all the records from three tables.
public void getAllRecords()
{
int searchId = 1;
Session currentSession = sessionFactory.getCurrentSession();
String query = "FROM Address as a, Fitness as f inner join a.personalInfo as p inner join f.personalInfo as p where p.candidateID=:userID";
Query theQuery = currentSession.createQuery(query);
theQuery.setParameter("userID", searchId);
List<?> list = theQuery.list();
for(int i=0; i<list.size(); i++) {
Object[] row = (Object[]) list.get(i);
System.out.println("Record"+i+": "+row[i]);
}
}
How can I correct this inner query?

You have to join all the three tables using CandidateID.
Try this:
FROM Address as a, Fitness as f, Personal_Info as p
WHERE p.CandidateID = a.CandidateID
AND p.CandidateID = f.UserID

Related

Join in Linq returns on matching records

Hi I am having two tables Country and city , country(id,Name) ,city(id,Country_id,City_name) When I am having Index action method as below , If I have 4 rows in country and there are two associated rows in cities then it only shows two rows on Country index table I mean only matched records
below is controller code I need to show all Country list even though there is any assocaited city in city table or now
var test1 = (from c in db.Cities
join cc in db.Countries
on c.Country_Id equals cc.Id into u
from cc1 in u.DefaultIfEmpty()
select new
{
Id = c.Id,
Name = c.Name,
Country_Id = c.Country.CountryName,
Code = c.Code,
IsActive = c.IsActive,
// IsActive = g.IsActive,
Date_Created = c.Date_Created,
Date_Modified = c.Date_Modified,
Latitude = c.Latitude,
Longitude = c.Longitude,
}).ToList();
return Json(new { data = test1 }, JsonRequestBehavior.AllowGet);

following linq performing left outer join instead of inner join

I cannot see where the problem lies with the following code. I am trying to retrieve those employees who are named as responsibles for certain vacancie. I have about 20 vacancies in my DB assigned to some 16 employees and about 1801 employee records in the employees table. The code always returns a result with 1801 entries.
from emp in container.Employees
join p in container.Vacancies
on emp.EMPID equals p.ResponsibleOfficer into j
group j by new {k1=emp.EMPID,k2=emp.NAME} into g
select new { EmpId = g.Key.k1, Name = g.Key.k2 , Count = g.Count()}
I want something similar to this
select emp.EmpId,emp.Name,Count(*) as count
from Vacancies p, Employees e
where p.ResponsibleOfficer=e.EmpId
group by e.EmpId,e.Name
any help is much appreciated. thanks
You're using join ... into. That will always return a single result for each element of the original sequence, even if there are no matches in the right sequence.
You can filter out entries with no elements in j using a where clause:
from emp in container.Employees
join p in container.Vacancies
on emp.EMPID equals p.ResponsibleOfficer into j
where j.Any()
group j by new {k1=emp.EMPID,k2=emp.NAME} into g
select new { EmpId = g.Key.k1, Name = g.Key.k2 , Count = g.Count()}
Or you could just use an inner join to start with - but I don't understand your current grouping well enough to see what you're trying to do. What is your group by clause for?
EDIT: If it was really just to group by employee, you're already doing that. You can change the code to:
from emp in container.Employees
join p in container.Vacancies
on emp.EMPID equals p.ResponsibleOfficer into j
where j.Any()
select new { Employee = emp, Count = j.Count()}
Basically, after the join you've got two range variables in scope: emp (the "current" employee) and j (all the relevant vacancies matching that employee). You're just trying to count j for each employee, right?
I'm using lambda, but works:
container
.Employees
.Join(container.Vacancies, l => l.EmpId, e => e.ResponsibleOfficer, (l, e) => new { l.EmpId, l.Name })
.GroupBy(g => new { g.EmpId, g.Name })
.Select(s => new { EmpId = s.Key.EmpId, Name = s.Key.Name, Count = s.Count() });

LINQ intersect?

I have two tables in form of these clases
public class Movie
{
private int MovieID;
private string Title;
}
public class transactions
{
private int TransactionID;
private int MovieID;
}
so first table contains ALL movies 2nd contains movies which are RENTED
How do I select ALL movies that are left in the store , ie not rented and are available. Tried soething like:
var moviesavailable =
(from m in db.Movies
select m.MovieID ).Intersect
(from trans in db.Transactions
select trans.MovieID)
but not working...
First way to do it is go over all movies and for each look if there is no transaction with the same MovieID:
db.Movies.Where(m => !db.Transactions.Any(t => t.MovieID == m.MovieID))
Second way is to make left join. We join all rows from Movies and their equivalent rows from Transactions. If there is no row in Transactions for a row in Movies, then for this row the transaction is null (DefaultIfEmpty):
from m in db.Movies
join t in db.Transactions on m.MovieID equals t.MovieID into g
from t in g.DefaultIfEmpty()
where t == null
select m.MovieID

Linq Nested Inner Joins

I want to join the following Tables
1. B_Book[1st Table]
-B_BID (Book ID)(PK)
-B_Name
-B_CategroyID (FK)
2. BI_BookInstance [2nd Table]
-BI_IID(Instance ID)
-BI_BID (FK)
-BI_Price
3. BC_BookCategory [3rd Table]
-BC_CategoryID (PK)
-BC_CategoryName
First Join B_Book and BI_BookInstance then join the result of those both with BookCategory.
(1st join)[B_BID equals BI_BID]
(2nd nested join)[result of 1st join B_CategoryID equals BC_CategoryID]
Edit
SQL would be something like the following:
SELECT * FROM
(SELECT * FROM B_Book b JOIN BI_BookInstance bi on b.B_BID = bi.BI_BID) as t1
JOIN BC_BookCategoryID bc on bc.BC_CategoryID = t1.B_CategoryID
What matches your query in LINQ would be the following (and you'll notice the similarity with SQL). I've also included some examples on how to rename the fields returned, such as Price or CategoryName:
var results = from b in B_Book
join bi in BI_BookInstance
on b.B_BID equals bi.BI_BID
join bc in BC_BookCategory
on b.B_CategoryID equals bc.BC_CategoryID
select new
{
// put in whatever fields you want returned here:
b.B_BID,
b.B_CategoryID,
b.B_Name,
bi.BI_BID,
bi.BI_IID,
Price = bi.BI_Price,
bc.BC_CategoryID,
CategoryName = bc.BC_CategoryName
};
I have supposed inner joins (your FKs is not null), so i would like query like this:
var ctx = new YourEntities();
var query = from b in ctx.B_Book
from bi in ctx.BI_BookInstance
from bc in ctx.BC_BookCategory
where b.B_BID == bi.BI_BID && b.B_CategoryID == bc.BC_CategoryID
select new
{
BInstID = bi.BI_IID,
BName = b.B_Name,
BPrice = bi.BI_Price,
BCategory = bc.BC_CategoryName
};
foreach (var item in query)
{
Console.WriteLine(item.BInstID);
Console.WriteLine(item.BName);
Console.WriteLine(item.BPrice);
Console.WriteLine(item.BCategory);
Console.WriteLine("");
}
You can do this without explicitly using linq's join statement, provided that navigation properties are in place:
from b in ctx.B_Book
from bi in b.BookInstances
select new { b.Property1, bi.Property2, b.BookCategory.Name }

Join statement in Linq to Sql

I need to write Join statment after writing query in linq
example :
var Query = (from Tab in Db.Employees
select Tab)
as i have some cases to perform join operation so
i need to do it on this Query Query.Join(Join with another Table like Department); I need the Syntax
if (DeptID != -1){ Query.Join(Join with table Department where FkDeptID = DeptID); }
Consider the usage of join in the LINQ 'query syntax':
from t1 in db.Table1
join t2 in db.Table2 on t1.field equals t2.field
select new { t1.field2, t2.field3}
Something like this?
var results = (from q in Query
join m in myList on q.SomeID = m.SomeID
select unknown);
Try using this query:
var Query =
from e in Db.Employees
join d in Db.Departments on e.FkDeptID equals d.DeptID into departments
select new
{
Employee = e,
Department = departments.SingleOrDefault(),
};
This works assuming that when e.FkDeptID == -1 that there is no record in the Departments table and in that case Department would be assigned null.
You should never have more than one department for an employee so I've used SingleOrDefault rather than FirstOrDefault.

Resources