How to Left Join two Parent-Child tables (i.e. 4 tables) - sql-server

We have the following database structure:
How can we query for all the data that belongs to a specific client and group? (An example written using Entity Framework 6 would be great.)
We could do something like this:
var parentChild1 = dbcontext.Parent1.Include(p => p.Child1).Select(p => p.ClientId = clientId).ToList();
var parentChild2 = dbcontext.Parent2.Include(p => p.Child2).Select(p => p.GroupId = groupId).ToList();
// And the manually join the values in parentChild2 with the objects in parentChild1.
// But there has to be a better way than this.
I'm thinking something like this; but can't figure out how to wire up child1(s) with child2(s):
void GetData(int clientId, int groupId)
{
var query = (from p1 in dbcontext.Parent1
from c1 in dbcontext.Child1
where p1.ClientId == clientId && c1.Parent1Id == p1.Id
join p2 in dbcontext.Parent2.Where(p2 => p2.GroupId == groupId)
on p1.Id equals p2.Parent1Id into p2groups
join c2 in dbcontext.Child2 on c1.Id equals c2.Child2Id into c2groups
from p2g in p2groups.DefaultIfEmpty()
from c2g in c2groups.DefaultIfEmpty()
select new Parent1
{
Parent2s = p2g,
//Child1s = c2g ??? How to wire up child1s with child2s?
};
}

The following sql statement should return all the data that belongs to a single parent1Id and groupId, from all the tables.
SELECT *
FROM Parent1 p1
LEFT JOIN Parent2 p2 ON(p1.Id = p2.Parent1Id AND p2.GroupId = #groupId)
LEFT JOIN Child1 c1 ON(p1.id = c1.Parent1Id)
LEFT JOIN Child2 c2 ON(c1.id = c2.Childe1Id AND p2.id = c2.Parent2Id)
WHERE p1.Id = #Id
The child joins are left joins since I assume not all parents have children, but the parents join is an inner join since you need the groupid as well as the parent1 id.

Related

SQL server 2012 - Query on retrieving matching records from a table by cross checking with two other tables

I have three tables (say A,B and C) with same column names and datatype. And these tables can be joined using four unique columns, say name,company,Seq_Number and role. Now I want to select records of particular role from table A and cross check them with the records in Table B and C.If they do not exist in both the tables, then we need to deactivate/remove those records from Table A. The problem is, the records which does not exist in table B might exist in Table C. So, I need to remove the records of particular role only if they don't exist in both B & C tables. I tried with the below query. But it is not returning the expected result. Kindly help me on this
SELECT DISTINCT FAT_Cust.name
, FAT_Cust.Company
, FAT_Cust.role
, FAT_Cust.Seq_Number
, Cust.name
, Cus.Company
, Cust.role
, Cust.Seq_Numberfrom (
SELECT DISTINCT ALC.NAME, ALC.Company, ALC.ROLE, ALC.Seq_Number
FROM AL_Customer ALC
INNER JOIN BL_Customer LPC ON ALC.NAME = LPC.NAME
AND ALC.Company = LPC.Company
AND ALC.ROLE = LPC.ROLE
AND ALC.Seq_Number = LPC.Seq_Number
AND ALC.Record_Active = 1
UNION SELECT DISTINCT ALC.NAME, ALC.Company, ALC.ROLE, ALC.Seq_Number
FROM AL_Customer ALC
INNER JOIN CL_Customer CLC ON ALC.NAME = CLC.NAME
AND ALC.Company = CLC.Company
AND ALC.ROLE = CLC.ROLE AND ALC.Seq_Number = CLC.Seq_Number
AND ALC.Record_Active = 1
) Cust
RIGHT OUTER JOIN AL_Customer FAT_Cust ON FAT_Cust.NAME = Cust.NAME
AND FAT_Cust.Company = Cust.Company
AND FAT_Cust.ROLE = Cust.ROLE
AND FAT_Cust.Seq_Number = Cust.Seq_Number
AND FAT_Cust.Record_Active = 1
WHERE Cust.NAME IS NULL
AND Cust.Company IS NULL
AND Cust.ROLE IS NULL
AND Cust.Seq_Number IS NULL
AND Cust.ROLE < > 'OWN'
Please try the query given below
SELECT ALC.* FROM AL_Customer ALC
LEFT JOIN BL_Customer BPC ON ALC.NAME = BPC.NAME
AND ALC.Company = BPC.Company
AND ALC.ROLE = BPC.ROLE
AND ALC.Seq_Number = BPC.Seq_Number
AND ALC.Record_Active = 1
AND BLC.Record_Active = 1
LEFT JOIN CL_Customer CPC ON ALC.NAME = CPC.NAME
AND ALC.Company = CPC.Company
AND ALC.ROLE = CPC.ROLE
AND ALC.Seq_Number = CPC.Seq_Number
AND ALC.Record_Active = 1
AND CLC.Record_Active = 1
WHERE ALC.Record_Active = 1
AND (BPC.NAME IS NULL)
AND (CPC.NAME IS NULL)
you can add more condition is where class to narrow down the matching criteria. the above query is assuming that name is present for all the records in the table. I hope this will resolve your issue.

Merge data when inserting into another table with the same ID

I have a table with the following data, the lab_sample_id are identical, I’m inserting this data into another table. I would like to merge the data when inserting into another table if the lab_sample_id is the same for leg_id 1 and 3.
leg_id 1 & 3 will always have unique data but the lab_sample_id might be identical.
Here's my current code:
INSERT INTO SAMPLE_RESULT
(PPK, LAB_SAMPLE_ID, LEG_ID, PT, PT_METHOD,
PT_MIN_DETECTION, CU, CU_METHOD, CU_MIN_DETECTION)
SELECT B.PK, CSR.LAB_SAMPLE_ID, CSR.LEG_ID, CSR.PT, CSR.PT_METHOD,
CSR.PT_MIN_DETECTION, CSR.CU, CSR.CU_METHOD, CSR.CU_MIN_DETECTION
FROM [SOURCE] S
JOIN CLEARING_BATCH CB ON CB.PPK = S.PK
JOIN CLEARING_SAMPLE_RESULT CSR ON CSR.PPK = CB.PK
JOIN SAMPLE_REG SR ON SR.FIELD_SAMP_ID = CSR.LAB_SAMPLE_ID
LEFT JOIN PROSPECTS_AND_MINES PM ON PM.PPK = S.PK
LEFT JOIN LABORATORY L ON L.PPK = PM.PK
LEFT JOIN BATCH B ON L.PK = B.PPK
WHERE CB.PK =#Submission_Pk
AND CB.BATCH_ID = B.BATCH_ID
AND NOT EXISTS(SELECT *
FROM SAMPLE_RESULT SR
WHERE SR.PPK = B.PK
AND SR.LAB_SAMPLE_ID = CSR.LAB_SAMPLE_ID
AND SR.LEG_ID = CSR.LEG_ID)
Something like this should do the trick, where you can JOIN the table to itself:
SELECT t1.LAB_SAMPLE_ID,
t1.LEG_ID,
t1.PT,
t1.PT_METHOD,
t1.PT_MIN_DETECTION,
t2.cu,
t2.CU_METHOD,
t2.CU_MIN_DETECTION
FROM CLEARING_SAMPLE_RESULT t1
INNER JOIN CLEARING_SAMPLE_RESULT t2
ON t1.LAB_SAMPLE_ID = t2.LAB_SAMPLE_ID
WHERE t1.LAB_SAMPLE_ID = 1 AND t2.LAB_SAMPLE_ID = 3
Then you can modify your UPDATE logic to use this data.

Sql query to Left Join in Linq to entity

I've below SQL query
Select LC.*,LP.[LandingPageName] from [LandingPageCompanies] LC
Left join [LandingPageContent] LP on LP.SubCategoryID=LC.SubCategoryID
where LC.[CategoryID]=17
And i need to convert it into LINQ to entity.
i've tried the following query, But it's working as Inner join
var data = (from t1 in dbSavingContainer.LandingPageCompanies
join t2 in dbSavingContainer.LandingPageContents on t1.SubCategoryID equals t2.SubCategoryID
where t1.CategoryID == CategoryID
select new
{
CategoryID = t1.CategoryID,
CompanyID = t1.CompanyID,
CompanyLink = t1.CompanyLink,
CompanyLogo = t1.CompanyLogo,
CompanyName = t1.CompanyName,
SubCategoryID = t1.SubCategoryID,
LandingPageName = t2.LandingPageName
}).ToList();
Where i'm lacking. ?
Thanks..i just solved it using below query ;)
var data = (from t1 in dbSavingContainer.LandingPageCompanies
join t2 in dbSavingContainer.LandingPageContents on t1.SubCategoryID equals t2.SubCategoryID
into x from y in x.DefaultIfEmpty()
where t1.CategoryID == CategoryID
select new
{
CategoryID = t1.CategoryID,
CompanyID = t1.CompanyID,
CompanyLink = t1.CompanyLink,
CompanyLogo = t1.CompanyLogo,
CompanyName = t1.CompanyName,
SubCategoryID = t1.SubCategoryID,
LandingPageName = y.LandingPageName
}).ToList();

Grouping by ShopName Count Different type of Customer(membership)

We have a 2 tables
Table 1
Shop where we have shop details
ShopNo, ShopName
Table 2
Customer where we have all customer details
CustomerId, CustomerName, MembershipType, ShopId
what we are trying to query is
ShopName SilverMember GoldMember LifeMember
ABC 45 110 1
XYZ 90 0 10
DEF 10 10 7
Is there a way to make it possible
if in Linq well and good else only sql query will do thanks in advance
Regards
Moksha
Something like this should do the trick:
select s.ShopName,
count(c1.CustomerId) as 'SilverMember',
count(c2.CustomerId) as 'GoldMember',
count(c3.CustomerId) as 'LifeMember'
from Shop s
left outer join Customer c1 on c1.ShopId = s.ShopNo and c1.MembershipType = 'SilverMember'
left outer join Customer c2 on c2.ShopId = s.ShopNo and c2.MembershipType = 'GoldMember'
left outer join Customer c3 on c3.ShopId = s.ShopNo and c3.MembershipType = 'LifeMember'
group by s.ShopName
Assuming MembershipType contains the actual VARCHAR values SilverMember, GoldMember, and LifeMember, this should work in T-SQL:
SELECT
[ShopName], COUNT([SilverMember]) AS [SilverMember], COUNT([GoldMember]) AS [GoldMember], COUNT([LifeMember]) AS [LifeMember]
FROM
[Table1]
INNER JOIN [Table2]
ON [Table1].[ShopNo] = [Table2].[ShopId]
PIVOT
(
MAX([MembershipType])
FOR [MembershipType] IN ([SilverMember], [GoldMember], [LifeMember])
) AS [P]
GROUP BY
[ShopName]
Example on SQL Fiddle
If you want to use linq:
var query = from s in context.Shops
join c in context.Customers on s.ShopNo equals c.ShopId
group c by s.ShopName into g
select new
{
ShopName = g.Key,
SilverMember = g.Count(c => c.MembershipType == "SilverMember"),
GoldMember= g.Count(c => c.MembershipType == "GoldMember"),
LifeMember= g.Count(c => c.MembershipType == "LifeMember"),
};

JOIN codition in SQL Server

After applying join condition on two tables I want records which is maximum among records of left table
My query
SELECT a1.*,
t.*,
( a1.trnratefrom - t.trnratefrom )AS minrate,
( a1.trnrateto - t.trnrateto ) AS maxrate
FROM (SELECT a.srno,
trndate,
b.trnsrno,
Upper(Rtrim(Ltrim(b.trnstate))) AS trnstate,
Upper(Rtrim(Ltrim(b.trnarea))) AS trnarea,
Upper(Rtrim(Ltrim(b.trnquality))) AS trnquality,
Upper(Rtrim(Ltrim(b.trnlength))) AS trnlength,
Upper(Rtrim(Ltrim(b.trnunit))) AS trnunit,
b.trnratefrom,
b.trnrateto,
a.remark,
entdate
FROM mstprodrates a
INNER JOIN trnprodrates b
ON a.srno = b.srno)a1
INNER JOIN (SELECT c.srno,
trndate,
d.trnsrno,
Upper(Rtrim(Ltrim(d.trnstate))) AS trnstate,
Upper(Rtrim(Ltrim(d.trnarea))) AS trnarea,
Upper(Rtrim(Ltrim(d.trnquality))) AS trnquality,
Upper(Rtrim(Ltrim(d.trnlength))) AS trnlength,
Upper(Rtrim(Ltrim(d.trnunit))) AS trnunit,
d.trnratefrom,
d.trnrateto,
c.remark,
entdate
FROM mstprodrates c
INNER JOIN trnprodrates d
ON c.srno = d.srno) AS t
ON a1.trnstate = t.trnstate
AND a1.trnquality = t.trnquality
AND a1.trnunit = t.trnunit
AND a1.trnlength = t.trnlength
AND a1.trnarea = t.trnarea
AND a1.remark = t.remark
WHERE t.srno = (SELECT MAX(srno)
FROM a1
WHERE srno < a1.srno)
If you mean to say,
you want Records exist in Left table but not in right then use LEFT OUTER JOIN.

Resources