LEFT OUTER JOIN IN ENTITY FRAMEWORK - entity-framework

I am trying left outer join entity framework by joining 4 tables:
var ssss = (from supplier in entity.Supplier_master
join city in entity.City_master on supplier.Supplier_City equals city.id
join state in entity.State_master on supplier.Supplier_State equals state.id
join country in entity.Country_master on supplier.Supplier_Country equals country.id
where supplier.Supplier_Code.Equals(sup_code)
select (new { supplier.Supplier_Code, supplier.Supplier_Name, city.City_Name, state.State_Name, country.Country_Name, supplier.Supplier_TradeMark })).ToList();
The above code is executed as inner join, please help me to find the solution to done left outer join.

Join the 2 table usering "into alias" then select from that result.
Example:
var query = from supplier in entity.Supplier_master
join city in entity.City_master on supplier.Supplier_City equals city.id into citySupplier
from cs in citySupplier.DefaultIfEmpty()
select new { your fields) };

Related

COALESCE TSQL with a join tsql

I have a requirement to pick up data that is in more than one place and I have some form of recognition if using the coalesce function. Basically I am looking to coalesce the join itself but looking online its seems as if i can only do this on the fields.
So we have a Products and Suppliers table, we also have these as a temp table so in total 4 tables (products, tempproducts, suppliers, tempsuppliers). In the suppliers and products table is where we store our products and suppliers and their temptables we store any new suppliers/products. We also have a tempsupplierproduct which joins new suppliers to new products. However we can end in a situation where a new supplier has an existing product so the new supplier will be in the tempsuppliers table and its product is in the products table NOT the tempproducts as it is not new, we will also have a new tempsupplierproduct to join the two up.
So i want a query which looks in the tempsupplierproducts table and then gets basic information about the supplier and products. To do this i am using a coalesce.
SELECT DISTINCT SP.*, COALESCE(P.Product, PD.Product) 'Product', COALESCE(S.Supplier, SU.Supplier) 'Supplier'
FROM tempsupplierproduct SP
LEFT JOIN tempProduct P ON SP.ProductCode = P.Code
LEFT JOIN Products PD ON SP.ProductCode = PD.Code
LEFT JOIN tempSupplier S ON SP.SupplierCode = S.Code
LEFT JOIN Suppliers SU ON SP.SupplierCode = SU.Code
Now while this works, something at the back of my head tells me it is not entirely right, ideally i want if data is not in table A then join to table B. I have seen maybe coalescing inside the join itself but I am unsure how to do this
LEFT JOIN Suppliers Su ON SP.SupplierCode = COALESCE(S.Code, SU.Code)
maybe away, but I am confused by this, all it is saying is use code in temptable if not there then use supplier code. So what would this mean if we have a code in the temptable, will this try to join on it, if so then this is incorrect also.
Any help is appreciated
You can union the two suppliers tables together and then join them in one go like this. I'm assuming that there are no duplicates between the two tables in this case but with a bit of extra work that could be resolved as well.
WITH AllSuppliers AS
(
SELECT Code, Supplier FROM Suppliers
UNION ALL
SELECT Code, Supplier FROM tempSupplier
)
SELECT DISTINCT SP.*, COALESCE(P.Product, PD.Product) 'Product', S.Supplier
FROM tempsupplierproduct SP
LEFT JOIN tempProduct P ON SP.ProductCode = P.Code
LEFT JOIN Products PD ON SP.ProductCode = PD.Code
LEFT JOIN AllSuppliers S ON SP.SupplierCode = S.Code
If you need to handle duplicates in the two suppliers tables then an approach like this should work, essentially we rank the duplicates and then pick the highest ranked result. For two tables you could use a full outer join between the two but this approach will scale to any number of tables.
WITH AllSuppliers AS
(
SELECT Code, Supplier, 1 AS TablePriority FROM Suppliers
UNION ALL
SELECT Code, Supplier, 2 AS TablePriority FROM tempSupplier
),
SuppliersRanked AS
(
SELECT Code, Supplier,
ROW_NUMBER() OVER (PARTITION BY Code ORDER BY TablePriority) AS RowPriority
FROM AllSuppliers
)
SELECT DISTINCT SP.*, COALESCE(P.Product, PD.Product) 'Product', S.Supplier
FROM tempsupplierproduct SP
LEFT JOIN tempProduct P ON SP.ProductCode = P.Code
LEFT JOIN Products PD ON SP.ProductCode = PD.Code
LEFT JOIN SuppliersRanked S ON SP.SupplierCode = S.Code
AND RowPriority = 1
You can absolutely join on a coalesced field. Here is a snippet from one of my production views:
LEFT JOIN [Portal].tblHelpdeskresource supplier ON PO.fld_str_SupplierID = supplier.fld_str_SupplierID
-- Job type a
LEFT JOIN [Portal].tblHelpDeskFault HDF ON PO.fld_int_HelpdeskFaultID = HDF.fld_int_ID
-- Job Type b
LEFT JOIN [Portal].tblProjectHeader PH ON PO.fld_int_ProjectHeaderID = PH.fld_int_ID
LEFT JOIN [Portal].tblPPMScheduleLine PSL ON PH.fld_int_PPMScheduleRef = PSL.fld_int_ID
-- Managers (used to be separate for a & b type, now converged)
LEFT JOIN [Portal].uvw_HelpDeskSiteManagers PSM ON COALESCE(PSL.fld_int_StoreID,HDF.fld_int_StoreID) = PSM.PortalSiteId
LEFT JOIN [Portal].tblHelpdeskResource PHDR ON PSM.PortalResourceId = PHDR.fld_int_ID

Double join postgres

I need to get the username value from the table "commons.user", using the field "peticion.id_usuario_gerente"
I do not know how to do a join or what is necessary for that field to bring me the value I really need "gerente"
peticion.id_usuario_gerente <-- Is an id that points to my table "commons.usuario"
SELECT empleado.id,
empleado.fecha_contratado,
empleado.fecha_fin_contrato,
empleado.persona_comun,
persona.nombre,
persona.apellido1,
persona.apellido2,
empleado.responsable,
peticion.id_peticion
peticion.id_usuario_gerente <-- need username
FROM rrhh.empleado as empleado
LEFT JOIN commons.persona as persona on empleado.persona_comun = persona.id
LEFT JOIN seleccion.peticion as peticion on empleado.peticion_contratacion = peticion.id_peticion;
You just need to add one more [left] join to your query.
SELECT empleado.id,
empleado.fecha_contratado,
empleado.fecha_fin_contrato,
empleado.persona_comun,
persona.nombre,
persona.apellido1,
persona.apellido2,
empleado.responsable,
peticion.id_peticion
peticion.id_usuario_gerente,
usuario_gerente.nombre -- the column name for the user name
FROM rrhh.empleado as empleado
LEFT JOIN commons.persona as persona
on empleado.persona_comun = persona.id
LEFT JOIN seleccion.peticion as peticion
on empleado.peticion_contratacion = peticion.id_peticion
LEFT JOIN commons.usuario as usuario_gerente -- additional join for the table
on peticion.id_usuario_gerente = usuario_gerente.id_usuario;

Why does not adding distinct in this query produce duplicate rows?

This query was taken from a Rails application log...I'm trying to edit a massive postgresql statement I didn't write....If I don't add a distinct keyword after the SELECT, 2 duplicate rows appear for each braintree account. Why is this and is there another way to avoid having to use the distinct to avoid duplicates?
EDIT: I understand what distinct is supposed to do, the reason I'm asking is that it doesn't generate duplicates for other toy lines. By other toy lines, this query is building a "table" for a particular toy id (this specific example toys.id = 12). How do I figure out where the duplicate rows are being generated?
SELECT accounts.braintree_account_id as braintree_account_id,
accounts.braintree_account_id as braintree_account_id, format('%s %s', addresses.first_name,
addresses.last_name) as shipping_address_full_name,
users.email as email, addresses.line_1 as shipping_address_line_1,
addresses.line_2 as shipping_address_line_2, addresses.city as
shipping_address_city, addresses.state as shipping_address_state,
addresses.zip as shipping_address_zip_code, addresses.country
as shipping_address_country, CASE WHEN xy_shirt IS NULL THEN '' ELSE xy_shirt END, plans.name as plan_name, toys.sku as sku, to_char(accounts.created_at, 'MM/DD/YYYY HH24:MM:SS') as
account_created_at,
to_char(accounts.next_assessment_at, 'MM/DD/YYYY HH24:MM:SS') as account_next_assessment_at,
accounts.account_status as account_status FROM \"accounts\" INNER JOIN \"addresses\" ON
\"addresses\".\"id\" = \"accounts\".\"shipping_address_id\" AND \"addresses\".\"type\" IN
('ShippingAddress') LEFT OUTER JOIN shipping_methods ON
shipping_methods.account_id = accounts.id LEFT OUTER JOIN plans ON
accounts.plan_id = plans.id
LEFT OUTER JOIN users ON
accounts.user_id = users.id LEFT OUTER JOIN toys ON plans.toy_id = toys.id
LEFT OUTER JOIN account_variations ON accounts.id =
account_variations.account_id LEFT OUTER JOIN variations ON
account_variations.variation_id = variations.id
LEFT OUTER JOIN
choice_value_variations ON variations.id =
choice_value_variations.variation_id
LEFT OUTER JOIN choice_values ON
choice_value_variations.choice_value_id = choice_values.id LEFT OUTER
JOIN choice_types ON choice_values.choice_type_id = choice_types.id
LEFT
OUTER JOIN choice_type_toys ON choice_type_toys.toy_id = toys.id
AND choice_type_toys.choice_type_id = choice_types.id
LEFT OUTER JOIN
(SELECT * FROM crosstab('SELECT accounts.id, choice_types.id,
choice_values.presentation FROM accounts\n
LEFT JOIN account_variations ON
accounts.id=account_variations.account_id\n
LEFT JOIN variations ON account_variations.variation_id=variations.id\n
LEFT JOIN choice_value_variations ON
variations.id=choice_value_variations.variation_id\n
LEFT JOIN choice_values ON
choice_value_variations.choice_value_id=choice_values.id\n
LEFT JOIN choice_types ON choice_values.choice_type_id=choice_types.id
ORDER BY 1,2',\n 'select distinct choice_types.id
from choice_types JOIN choice_values ON choice_values.choice_type_id =
choice_types.id JOIN choice_value_variations ON
choice_value_variations.choice_value_id = choice_values.id JOIN
variations ON choice_value_variations.variation_id = variations.id JOIN choice_type_toys ON choice_type_toys.choice_type_id = choice_types.id JOIN toys ON toys.id = choice_type_toys.toy_id
where toys.id=12 ORDER
BY choice_types.id ASC')\n
AS (account_id int, xy_shirt
VARCHAR)) account_variation_view\n ON
accounts.id=account_variation_view.account_id WHERE
\"accounts\".\"account_status\" = 'active' AND
\"addresses\".\"flagged_invalid_at\" IS NULL AND \"toys\".\"id\" = 12
AND (NOT EXISTS (SELECT \"account_skipped_months\".* FROM
\"account_skipped_months\" WHERE
\"account_skipped_months\".\"month_year\" = 'JUL2016' AND
(account_skipped_months.account_id = accounts.id)))"
The purpose of using DISTINCT in a SELECT statement is to eliminate duplicate rows.

PostgreSQL how to use count with boolean true value only

I'm trying to get 2 columns. One with only true values of patient_healty and second with all values of patient_healty from department.
select
count(p1.patient_health) as not_health,
count(patient.id) as all,
department.name
from
department
inner join
doctor on department.id = doctor.department_id
inner join
healing on doctor.id = healing.doctor_id
inner join
patient as p1 on healing.patient_id = p1.id
inner join
patient on healing.patient_id = patient.id
group by
department.name
This will return two columns of all values from patient_health and name of the department. Thanks
If I understand correctly, you can use avg():
select avg(p1.patient_health::int)

JPQL left outer join does unnecessary joins

I've got the following JPQL :
SELECT a.b.id, a.b.name, a.c.id,a.c.name
left join a.b left join a.c
group by a.b.id,a.b.name,a.c.id,a.c.name
now b and c are both referencing the same table.
the generated SQL is doing the left join I asked, and another join for a.b.name and a.c.name
(which is unnecessary because the left join includes the name, and it retrieves more results than expected)
how do I make the SQL generated not include the unnecessary join?
1 solution came up is not select the names and retrieve them individually by a different query.. but it's not the most elegant way I suppose..
(btw I tried selecting a.b,a.c and group by a.b,a.c but it throws ORA not a group by expression because the generated sql retrieves all rows but group by is only by ID)
and the left join is necessary since I want to allow null values.
Thanks a lot.
SELECT a.b.id, a.b.name, a.c.id,a.c.name
The above implicitly creates an inner join between a abd b,a nd another inner join between a and c. The query should be
select b.id, b.name, c.id, c.name
from A a
left join a.b b
left join a.c c
The group by clause doesn't make any sense, since you have no aggregate in your select clause. group by would be useful if you had, for example
select b.id, b.name, c.id, c.name, count(c.foo)
from A a
left join a.b b
left join a.c c
group by b.id, b.name, c.id, c.name