I have 2 tables as attached image:
In order to save space, i only store the ID.
In the gridview, i want to show the name based on the ID.
I tried on inner join but only 1 parameter can be inner join.
Any direction can i go? Please help.
Here is the code i tried:
SelectCommand="SELECT * FROM [ProjectInfo] inner join [Employee] ON Employee.ID = ProjectInfo.ProjectInfo_Leader AND Employee.ID = ProjectInfo.ProjectInfo_CoLeader AND Employee.ID = ProjectInfo.ProjectInfo_Helper"
SelectCommand="SELECT * FROM [ProjectInfo] inner join [Employee] ON Employee.ID = ProjectInfo.ProjectInfo_Leader OR Employee.ID = ProjectInfo.ProjectInfo_CoLeader OR Employee.ID = ProjectInfo.ProjectInfo_Helper"
I am not familiar with SQL, thus i can only try and error...
Thanks.
It is obvious solution.
select l.name leader,c.name [co-lider],h.name helper
from role r
left join people l on r.lider=l.id
left join people c on r.[co-lider]=c.id
left join people h on r.helper=h.id
Note: it is better to use left join in case some roles are not filled.
Related
Syntax Error (missing Operator) in query expression 'tbl_employee.emp_id = tbl_netpay.emp_id INNER JOIN tbl_gross ON tbl_employee.emp_id = tbl_gross.emp_ID INNER JOIN tbl_tax ON tbl_employee.emp_id - tbl_tax.emp_ID'.
SELECT tbl_employee.emp_ID,
tbl_employee.emp_name,
tbl_gross.BasicSalary,
tbl_gross.totalOT,
tbl_netpay.totalGross,
tbl_tax.totalLate,
tbl_tax.allowance,
tbl_tax.SSS,
tbl_tax.PhilHealth,
tbl_tax.GSIS,
tbl_tax.HDMF,
tbl_netpay.totalDeduc,
tbl_netpay.emp_ti,
tbl_netpay.emp_wt,
tbl_netpay.emp_np
FROM tbl_employee
INNER JOIN tbl_netpay ON tbl_employee.emp_id = tbl_netpay.emp_id
INNER JOIN tbl_gross ON tbl_employee.emp_id = tbl_gross.emp_ID
INNER JOIN tbl_tax ON tbl_employee.emp_id = tbl_tax.emp_ID;
I always get the error above.
Access requires parentheses in the FROM clause for queries which include more than one join. Try it this way ...
FROM
((tbl_employee
INNER JOIN tbl_netpay
ON tbl_employee.emp_id = tbl_netpay.emp_id)
INNER JOIN tbl_gross
ON tbl_employee.emp_id = tbl_gross.emp_ID)
INNER JOIN tbl_tax
ON tbl_employee.emp_id = tbl_tax.emp_ID;
If possible, use the Access query designer to set up your joins. The designer will add parentheses as required to keep the db engine happy.
Thanks HansUp for your answer, it is very helpful and it works!
I found three patterns working in Access, yours is the best, because it works in all cases.
INNER JOIN, your variant. I will call it "closed set pattern".
It is possible to join more than two tables to the same table with good performance only with this pattern.
SELECT C_Name, cr.P_FirstName+" "+cr.P_SurName AS ClassRepresentativ, cr2.P_FirstName+" "+cr2.P_SurName AS ClassRepresentativ2nd
FROM
((class
INNER JOIN person AS cr
ON class.C_P_ClassRep=cr.P_Nr
)
INNER JOIN person AS cr2
ON class.C_P_ClassRep2nd=cr2.P_Nr
)
;
INNER JOIN "chained-set pattern"
SELECT C_Name, cr.P_FirstName+" "+cr.P_SurName AS ClassRepresentativ, cr2.P_FirstName+" "+cr2.P_SurName AS ClassRepresentativ2nd
FROM person AS cr
INNER JOIN ( class
INNER JOIN ( person AS cr2
) ON class.C_P_ClassRep2nd=cr2.P_Nr
) ON class.C_P_ClassRep=cr.P_Nr
;
CROSS JOIN with WHERE
SELECT C_Name, cr.P_FirstName+" "+cr.P_SurName AS ClassRepresentativ, cr2.P_FirstName+" "+cr2.P_SurName AS ClassRepresentativ2nd
FROM class, person AS cr, person AS cr2
WHERE class.C_P_ClassRep=cr.P_Nr AND class.C_P_ClassRep2nd=cr2.P_Nr
;
I want to update the table with multiple inner join query but when I write the query it through an error incorrect syntax near inner keyword
Update inventory_detail INNER JOIN inventory
ON inventory_detail.inventory_id = Inventory.Inventory_id
INNER JOIN Ingredients
ON Inventory.Inventory_id=Ingredients.invenotry_id
SET inventory_detail.Quantity=inventory_detail.Quantity-1
WHERE inventory_detail.loc_id =1 AND Ingredients.item_id=27 ;
ERD diagram
Change your query to:
UPDATE inventory_detail
SET Quantity = Quantity - 1
FROM inventory_detail
INNER JOIN inventory
ON inventory_detail.inventory_id = Inventory.Inventory_id
INNER JOIN Ingredients
ON Inventory.Inventory_id = Ingredients.invenotry_id
WHERE inventory_detail.loc_id = 1
AND Ingredients.item_id = 27;
I've been following a few examples from this website on how to create Linq Left Outer Join queries but I haven't found any examples of where the "outer key in the left join doesn't point to the inner key but instead points to a previous key". Bear with me for that phrasing I know it's not correct but have a look at the following snippets of code and maybe it will be clearer.
Specifically, see the first left join where sp.SalesPersonID = j.SalesPersonID.
select rt.Name as ResourceType, s.FirstName + ' ' + s.Surname as Supervisor, sp.FirstName + ' ' + sp.LastName as SalesPerson, tr.OrderCodeID, tr.SkillID
, j.CustomerName, j.JobNumber
from dbo.TaskResource tr join projects.Task t on t.ID = tr.taskiD
join dbo.ResourceType rt on rt.ID = tr.ResourceTypeID
join projects.projecttask pt on pt.taskid = tr.taskid
join projects.jobproject jp on jp.projectid = pt.projectid
join crm.tbljobs j on j.jobid = jp.jobid
left join common.tblSalesPersons sp on sp.SalesPersonID = j.SalesPersonID
left join common.tblSupervisors s on s.SupervisorID = j.SupervisorID
where JobDeleted is null or JobDeleted = 0
order by ResourceType
When converted to Linq it would make
...from j in temp1.DefaultIfEmpty()
join sp in dbc.tblSalesPersons on j.SalesPersonID equals sp.SalesPersonID into temp2
So far so good. But when I do the next left join I though it would just be the same thing but pointing to one of the previous keys as I mentioned earlier so instead of using the sp variable which I've seen several examples of, I use the j variable which is from a previous join:
from sp in temp2.DefaultIfEmpty()
join s in dbc.tblSupervisors on j.SupervisorID equals s.SupervisorID
Here is the full code snippet:
List<ResourceTreeObject> resourceTreeObjects = (
from tr in dbc.TaskResources
join t in dbc.Tasks on tr.TaskID equals t.ID
join rt in dbc.ResourceTypes on tr.ResourceTypeID equals rt.ID
join pt in dbc.ProjectTasks on tr.TaskID equals pt.TaskID
join jp in dbc.JobProjects on pt.ProjectID equals jp.ProjectID
join j in dbc.tblJobs on jp.JobID equals j.JobID into temp1
from j in temp1.DefaultIfEmpty()
join sp in dbc.tblSalesPersons on j.SalesPersonID equals sp.SalesPersonID into temp2
from sp in temp2.DefaultIfEmpty()
join s in dbc.tblSupervisors on j.SupervisorID equals s.SupervisorID
where j.JobDeleted == null || j.JobDeleted == 0
select new ResourceTreeObject
{
TaskResourceID = tr.ID
,
TaskID = tr.TaskID
,
ResourceTypeID = tr.ResourceTypeID
,
ResourceType = rt.Name
,
SkillID = tr.SkillID
,
OrderCodeID = tr.OrderCodeID
,
PermissionID = tr.PermissionID
,
JobID = j.JobID
,
JobNumber = j.JobNumber
,
CustomerName = j.CustomerName
,
Salesperson = sp.FirstName + " " + sp.LastName
,
Supervisor = s.FirstName + " " + s.Surname
}).ToList();
And this results in the wrong query. The last "left join" is treated like an inner join and returns the wrong number of rows. So in essence what I'm asking is, how do I (in LinQ) do two consecutive left outer joins after doing several consecutive inner joins but use the key from one of the previous tables in my left out join?
Also I'm not sure what the correct terminology for inner/outer keys etc. hence the awkward phrasing and title. Perhaps someone could correct that so it would be more beneficial to others. Thank you.
Your LINQ translation is just a little off.
The SQL has an inner join on crm.tbljobs followed by outer joins on common.tblSalesPerson and common.tblSupervisors.
The LINQ has outer joins on dbc.tblJobs and dbc.tblSalesPersons followed by an inner join on dbc.tblSupervisors.
into temp1 ... from j in in temp1.DefaultIfEmpty() makes the outer join happen on the table introduced prior to the into, which is dbc.tblJobs.
So it should be:
...
// inner join
join j in dbc.tblJobs on jp.JobID equals j.JobID
// left outer join
join sp in dbc.tblSalesPersons on j.SalesPersonID equals sp.SalesPersonID into salesPersons
from sp in salesPersons.DefaultIfEmpty()
// left outer join
join s in dbc.tblSupervisors on j.SupervisorID equals s.SupervisorID into supervisors
from s in supervisors.DefaultIfEmpty()
...
I changed temp1 and temp2 to more meaningful names to demonstrate what they represent in the outer join syntax. Note the relationship and relative position of dbc.tblSalesPersons to salesPersons, for example.
One more thing to remember is that sp and s can be null, so make sure you check for that before accessing their FirstName, LastName, and Surname properties.
I am trying to select the most recent record. Right now it is returning all records. Which makes since, because I have not put in a filter to get most recent, I am unsure of how to do that. Here is my code:
select
c.my_Name, a.my_Num, d.myBrand, a.order_bill, a.myDate
from
[table1] a
left join
[table2] b on a.[myCode] = b.[myCode]
left join
[table3] c on c.myTag = b.myTag
left join
[table4] d on a.[myHash] = d.[myHash]
where
c.[myName] = 'test name'
I am wanting to get most recent record from the table, I am guessing the most efficient way is to get most recent a.myDate.
I'd write
SELECT TOP 1
c.my_Name, a.my_Num, d.myBrand, a.order_bill, CONVERT(char(10), a.myDate,126)
FROM [table1] a
LEFT JOIN [table2] b on a.[myCode] = b.[myCode]
LEFT JOIN [table3] c on c.myTag=b.myTag
LEFT JOIN [table4] d on a.[myHash] = d.[myHash]
WHERE c.[myName] = 'test name'
ORDER BY a.myDate DESC
Something like this might help
select c.my_Name, a.my_Num, d.myBrand, a.order_bill, MAX(a.myDate)
from [table1] a
left join [table2] b on a.[myCode] = b.[myCode]
left join [table3] c on c.myTag=b.myTag
left join [table4] d on a.[myHash] = d.[myHash]
where c.[myName] = 'test name'
group by c.my_Name, a.my_Num, d.myBrand, a.order_bill
order by a.myDate DESC
This will grab distinct records with the greatest (most recent) a.myDate, grouped by your other elements.
Be aware of duplicates. Use your duplicate criteria keys in the select statement, or whatever elements you absolutely need to be distinct.
I have the following SQL query
SELECT
r.BEZEICHNUNG AS BEZEICHNUNG, r.ID AS ID,
ra.BEZEICHNUNG AS raumBEZEICHNUNG, ra.ID AS raumID
FROM
RAUM r
INNER JOIN RAZUORDNUNG rz ON rz.RAUM_ID = r.ID
INNER JOIN RAUMATTRIBUTE ra ON rz.RAUMATTRIBUTE_ID = ra.ID
WHERE
RAUMKLASSE_ID = ISNULL(#Raumklasse_ID, RAUMKLASSE_ID)
AND STADT_ID = ISNULL(#Stadt_ID, STADT_ID)
AND GEBAEUDE_ID = ISNULL(#Gebaeude_ID, GEBAEUDE_ID)
AND REGION_ID = ISNULL(#Region_ID, REGION_ID)
AND RAUMATTRIBUTE_ID = ISNULL(#Raumattribute_ID, RAUMATTRIBUTE_ID)
But I think that something is wrong with that.
For example:
If I put three in the RAUMKLASSE_ID textfield in the browser and invoke my method it returns only one room. But there are six rooms with that ID. The strange thing is, that if I remove the two INNER JOIN and the second line of my SELECT, like this:
SELECT
r.BEZEICHNUNG AS BEZEICHNUNG, r.ID AS ID
FROM
RAUM r
WHERE
RAUMKLASSE_ID = ISNULL(#Raumklasse_ID, RAUMKLASSE_ID)
AND STADT_ID = ISNULL(#Stadt_ID, STADT_ID)
AND GEBAEUDE_ID = ISNULL(#Gebaeude_ID, GEBAEUDE_ID)
AND REGION_ID = ISNULL(#Region_ID, REGION_ID)
AND RAUMATTRIBUTE_ID = ISNULL(#Raumattribute_ID, RAUMATTRIBUTE_ID)
it is returning the six rooms, which is correct. I don't know what the problem is with my query. Maybe someone can help me with that?
Thanks in advance
This is the expected behaviour, since:
FROM RAUM r
INNER JOIN RAZUORDNUNG rz ON rz.RAUM_ID = r.ID
INNER JOIN RAUMATTRIBUTE ra ON rz.RAUMATTRIBUTE_ID = ra.ID
Will get you only the rooms that are found in the tables RAUM, RAZUORDNUNG and RAUMATTRIBUTE tables, removing these INNER JOINs will get you all the rooms from the RAUM table that satisfy your condition, check these pages for more details about JOINs:
A visual explanation for JOINs.
Wikipedia article about JOINs
INNER JOIN won't return RAUM entries that have no corresponding RAZUORDNUNG or RAUMATTRIBUTE. You may need a LEFT JOIN instead; in this case, raumBEZEICHNUNG and raumID may be null in the returned set.