How to perform Linq to Entites Left Outer Join - entity-framework

I have read plenty of blog posts and have yet to find a clear and simple example of how to perform a LEFT OUTER JOIN between two tables. The Wikipedia article on joins Join (SQL) provides this simple model:
CREATE TABLE `employee` (
`LastName` varchar(25),
`DepartmentID` int(4),
UNIQUE KEY `LastName` (`LastName`)
);
CREATE TABLE `department` (
`DepartmentID` int(4),
`DepartmentName` varchar(25),
UNIQUE KEY `DepartmentID` (`DepartmentID`)
);
Assume we had a EmployeeSet as an employee container ObjectSet<Employee> EmployeeSet and a DepartmentSet ObjectSet<Department> DepartmentSet. How would you perform the following query using Linq?
SELECT LastName, DepartmentName
FROM employee e
LEFT JOIN department d
ON e.DepartmentID = d.DepartmentID

I would write this, which is far simpler than join and does exactly the same thing:
var q = from e in db.EmployeeSet
select new
{
LastName = e.LastName,
DepartmentName = e.Department.DepartmentName
};

You need to use the DefaultIfEmpty method :
var query =
from e in db.EmployeeSet
join d in db.DepartmentSet on e.DepartmentID equals d.DepartmentID into temp
from d in temp.DefaultIfEmpty()
select new { Employee = e, Department = d };

Related

Postgresql, how to SELECT json object without duplicated rows

I'm trying to find out how to get JSON object results of selected rows, and not to show duplicated rows.
My current query:
SELECT DISTINCT ON (vp.id) jsonb_agg(jsonb_build_object('affiliate',a.*)) as affiliates, jsonb_agg(jsonb_build_object('vendor',vp.*)) as vendors FROM
affiliates a
INNER JOIN related_affiliates ra ON a.id = ra.affiliate_id
INNER JOIN related_vendors rv ON ra.product_id = rv.product_id
INNER JOIN vendor_partners vp ON rv.vendor_partner_id = vp.id
WHERE ra.product_id = 79 AND a.is_active = true
GROUP BY vp.id
The results that I receive from this is:
[
affiliates: {
affiliate: affiliate1
affiliate: affiliate2
},
vendors: {
vendor: vendor1,
vendor: vendor1,
}
As you can see in the second record, vendor is still vendor1 because there are no more results, so I'd like to also know if there's a way to remove duplicates.
Thanks.
First point : the result you display here above doesn't conform the json type : the keys are not double-quoted, the string values are not double-quoted, having dupplicated keys in the same json object ('{"affiliate": "affiliate1", "affiliate": "affiliate2"}' :: json) is not be accepted with the jsonb type (but it is with the json type).
Second point : you can try to add the DISTINCT key word directly in the jsonb_agg function :
jsonb_agg(DISTINCT jsonb_build_object('vendor',vp.*))
and remove the DISTINCT ON (vp.id) clause.
You can also add an ORDER BY clause directly in any aggregate function. For more information, see the manual.
You could aggregate first, then join on the results of the aggregates:
SELECT a.affiliates, v.vendors
FROM (
select af.id, jsonb_agg(jsonb_build_object('affiliate',af.*)) as affiliates
from affiliates af
group by af.id
) a
JOIN related_affiliates ra ON a.id = ra.affiliate_id
JOIN related_vendors rv ON ra.product_id = rv.product_id
JOIN (
select vp.id, jsonb_agg(jsonb_build_object('vendor',vp.*)) as vendors
from vendor_partners vp
group by vp.id
) v ON rv.vendor_partner_id = v.id
WHERE ra.product_id = 79
AND a.is_active = true

LINQ from objects Left Join

I have a linq query that works fine when I join two tables, but when I include another table, it does not return data. Please help me figure out what I am doing wrong.
First Linq returns data:
var q = (from c in _context.Complaint
join cl in _context.Checklist on c.COMP_ID equals cl.COMP_ID into clleft
from cls in clleft.DefaultIfEmpty()
orderby c.timestamp descending
select new
{
FileNum = c.FileNum
}).AsQueryable().Distinct();
return q;
When I add this table, no data returns
var q = (from c in _context.Complaint
join cl in _context.Checklist on c.COMP_ID equals cl.COMP_ID into clleft
from cls in clleft.DefaultIfEmpty()
join oim in _context.OIM_EMPLOYEE on cls.MonitorEnteredEmpID equals oim.EmpID into oimleft
from oims in oimleft.DefaultIfEmpty()
orderby c.timestamp descending
select new
{FileNum = c.FileNum
}).AsQueryable().Distinct();
return q;

SQL query for finding Foreign key constraints

I have one column , and i want to find in How many table that column used as foreign and also name of the table in which that column is used. I have PostgreSQL database . and i am using PG admin tool
select R.TABLE_NAME from INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE u
inner join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS FK
on U.CONSTRAINT_CATALOG = FK.UNIQUE_CONSTRAINT_CATALOG
and U.CONSTRAINT_SCHEMA = FK.UNIQUE_CONSTRAINT_SCHEMA
and U.CONSTRAINT_NAME = FK.UNIQUE_CONSTRAINT_NAME inner join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE R
ON R.CONSTRAINT_CATALOG = FK.CONSTRAINT_CATALOG
AND R.CONSTRAINT_SCHEMA = FK.CONSTRAINT_SCHEMA
AND R.CONSTRAINT_NAME = FK.CONSTRAINT_NAME WHERE U.COLUMN_NAME='M_InLine_ID'
AND U.TABLE_NAME = 'M_InLine'
I tried above query but it snot given any output
Please help me out

How to integrate WITH Recursive in a Querydsl query

I'm new to Querydsl and I'm struggling to figure out how to implement the following query:
WITH RECURSIVE results AS
(
SELECT id,
parent_id
FROM project
WHERE id = '8a3d6714-27fa-4d1f-962f-9047d616ab42'
UNION ALL
SELECT t.id,
t.parent_id
FROM project t
INNER JOIN results r ON r.parent_id = t.id
)
SELECT *
FROM results;
Its objective is to, starting from the bottom of a hierarchy, collect the anchor's parent (8a3d6714-27fa-4d1f-962f-9047d616ab42 in the above example; there is only one parent per row) all the way up to a point where there is a element without a parent. If successful, using my database, it should yield the following:
id parent_id
------------------------------------ ------------------------------------
8a3d6714-27fa-4d1f-962f-9047d616ab42 babc74e8-1b6f-49e8-a1e3-a176fce2975d
babc74e8-1b6f-49e8-a1e3-a176fce2975d 3f83c9a2-bf43-46d8-bf87-070f5b55ae5a
3f83c9a2-bf43-46d8-bf87-070f5b55ae5a 69c074c6-a329-42c3-8e2e-5da9ab0ef81e
69c074c6-a329-42c3-8e2e-5da9ab0ef81e bccab264-027c-4c4f-9ae8-3409efc6aeb3
bccab264-027c-4c4f-9ae8-3409efc6aeb3 227db39a-2219-4abb-a2a7-3d28bf47ac01
227db39a-2219-4abb-a2a7-3d28bf47ac01
Any thoughts would be much appreciated.
Regards
Rodrigo
QProjects results = new QProjects("results");
QProjects p = new QProjects("p");
QProjects t = new QProjects("t");
String id = "8a3d6714-27fa-4d1f-962f-9047d616ab42";
query.withRecursive(results, subQuery()
.unionAll(
subQuery().from(p).where(p.id.eq(id)).list(p.id, p.parentId),
subQuery().from(t).innerJoin(results).on(results.parentId.eq(t.id)).list(t.id, t.parentId)))
.from(results)
.list(results.id, results.parentId);

postgresql multi join syntax

SELECT sessions_compare.*
FROM archive_sessions as f_session, sessions_compare
LEFT JOIN archive_sessions as s_session ON (s_session.id = sessions_compare.second_session_id)
LEFT JOIN consols as f_consol ON (f_session.console_id = f_consol.id)
where sessions_compare.first_session_id = f_session.id
after executing a get error like
ERROR: invalid reference to FROM-clause entry for table "f_session"
LINE 13:
LEFT JOIN consols as f_consol ON (f_session.console_id
=...
HINT: There is an entry for table "f_session", but it cannot be referenced from this
part of the query.
When i switch places and have from like sessions_compare, archive_sessions as f_session
i get error like
ERROR: invalid reference to FROM-clause entry for table
"sessions_compare"
LINE 4: ... archive_sessions as s_session ON
(s_session.id = sessions_c...
HINT: There is an entry for table "sessions_compare", but it cannot be
referenced from this part of the query.
And only thing that work is
SELECT sessions_compare.*
FROM sessions_compare
LEFT JOIN archive_sessions as s_session ON (s_session.id = sessions_compare.second_session_id)
,archive_sessions as f_session
LEFT JOIN consols as f_consol ON (f_session.console_id = f_consol.id)
where sessions_compare.first_session_id = f_session.id
And my question is it normal ?? Im young in Postgresql in mysql when using multiple join from tables needed to be in ()
Yes, that's documented behavior in PostgreSQL.
In any case JOIN binds more tightly than the commas separating FROM items.
That means PostgreSQL acts like it builds its working table by evaluating the JOIN clauses before evaluating a comma-list in the FROM clause.
Best practice is generally considered to be to always use JOIN clauses; never put more than one table name in the FROM clause.
Changing the main query to a JOIN (and adding/shortening some correlation names) seems to fix the problem.
DROP SCHEMA fuzz CASCADE;
CREATE SCHEMA fuzz;
SET search_path='fuzz';
create table archive_sessions ( id INTEGER NOT NULL
, console_id INTEGER NOT NULL, game_id INTEGER NOT NULL);
create table sessions_compare (first_session_id INTEGER NOT NULL
, second_session_id INTEGER NOT NULL);
create table consols (id INTEGER NOT NULL);
create table games (id INTEGER NOT NULL);
create table localizations ( consols_id INTEGER NOT NULL, bars_id INTEGER NOT NULL);
create table bars ( id_bars INTEGER NOT NULL, area_id INTEGER NOT NULL);
create table areas ( id_areas INTEGER NOT NULL );
SELECT sco.*
FROM archive_sessions as ase
JOIN sessions_compare sco ON sco.first_session_id = ase.id
LEFT JOIN archive_sessions as ss ON (ss.id = sco.second_session_id)
LEFT JOIN consols as sc ON (ss.console_id = sc.id)
LEFT JOIN games as sg ON (ss.game_id = sg.id)
LEFT JOIN localizations as sl ON (sc.id = sl.consols_id)
LEFT JOIN bars as sb ON (sl.bars_id = sb.id_bars)
LEFT JOIN areas as sa ON (sb.area_id = sa.id_areas)
LEFT JOIN consols as fc ON (ase.console_id = fc.id)
LEFT JOIN games as fg ON (ase.game_id = fg.id)
LEFT JOIN localizations as fl ON (fc.id = fl.consols_id)
LEFT JOIN bars as fb ON (fl.bars_id = fb.id_bars)
LEFT JOIN areas as fa ON (fb.area_id = fa.id_areas)
-- WHERE sco.first_session_id = ase.id
;