Get distinct data from 2 tables using join - sql-server

Below is my query . I take socail sercurity no from Employee table and match it with child_excel table. Using that I get Employee ID and matching that with EmployeeCh table (which has employee ID). The employee has 2 child's so when I put the gender clause I get 4 records 2 for each child with different (i.e Male, Female) for each of the child's. I want only 2 rows for child 1 for each child with their respective genders.
SELECT distinct
[SSN],
empch2.GenderID,
gen.Name1
FROM [child_excel] as t
INNER JOIN Employee as empch on t.SSN = empch.SocialSecurityNo
INNER JOIN EmployeeCh as empch2 on empch.ID = empch2.EmployeeID
INNER JOIN Gender as gen on empch2.GenderID = gen.ID
I am getting O/p as
12345 1 Male
12345 2 Female
99999 1 Male
99999 2 Female
Expected output is
12345 1 Male
99999 2 Female
But when I add First Name in the join it gives proper output. I dnt want to use first Name
SELECT distinct
[SSN],
empch2.GenderID,
gen.Name1
FROM [child_excel] as t
INNER JOIN Employee as empch on t.SSN = empch.SocialSecurityNo
INNER JOIN EmployeeCh as empch2 on empch.ID = empch2.EmployeeID and t.First_Name= empch2.FirstName
INNER JOIN Gender as gen on empch2.GenderID = gen.ID

Use ROW_NUMBER ()
Select * from (
SELECT distinct
[SSN],
empch2.GenderID,
gen.Name1,
ROW_NUMBER()OVER(PARTITION BY [SSN] ORDER BY empch2.GenderID)RN
FROM [child_excel] as t
INNER JOIN Employee as empch on t.SSN = empch.SocialSecurityNo
INNER JOIN EmployeeCh as empch2 on empch.ID = empch2.EmployeeID and t.First_Name= empch2.FirstName
INNER JOIN Gender as gen on empch2.GenderID = gen.ID )T
WHERE T.RN = 1

Related

SQL Server Nearest Date

I have a table of persons and a table of addresses. The persons table contains one instance of the person and the addresses table can contain multiple instances of a person. The persons table contains a date added field and the addresses table also contains a date added field. How do I find the nearest date before or on in the addresses table and then match that to the persons table so only one address is returned?
This is the SQL I have to do a basic join for an exact match:
select p.personid,a.addressid,p.dateadded,a.dateadded
from persons p inner join a
on p.personid = a.personid and
p.dateadded = a.dateadded
Edit: here are the persons table and addresses table:
personid dateadded
1 01/01/2015
2 30/09/2014
3 01/08/2015
addressid personid dateadded
1 1 01/01/2015
2 2 16/02/2013
3 2 03/12/2013
4 3 19/05/2012
5 3 30/07/2015
6 3 07/09/2015
And here is the output I'm trying for:
personid addressid dateadded_person dateadded_address
1 1 01/01/2015 01/01/2015
2 3 30/09/2014 03/12/2013
3 6 01/08/2015 30/07/2015
Thanks
This is the general approach that doesn't involve top or analytic functions.
Based on your comment I edited to change the logic that finds which address is the most relevant. This version takes the person then joins to addresses and takes only those addresses added before the person was. The person_id and maximum (latest) dateadded are captured. After that it's just another join again to addresses to pick up the single row you're interested in.
select ...
from
persons as p
inner join
(
select personid, max(a.dateadded) as dateadded
from person as p inner join addresses as a on a.personid = p.personid
where a.dateadded <= p.dateadded
group by person
) as most_recent
on most_recent.personid = p.personid
inner join address as a
on a.personid = p.person_id and a.dateadded = most_recent.dateadded
You might also like cross apply:
select ...
from
persons as p
cross apply (
select max(a.dateadded) as most_recent from addresses as a
where a.personid = p.personid and a.dateadded <= p.dateadded
) as mr
inner join address as a
on a.personid = p.person_id and a.dateadded = mr.most_recent

remove duplicates based on column in inner join

This is returning exactly what I want, except some rows need to be removed because the inner join has matched multiple rows when I only want it to match the first match.
select table1.IDa, table1.IDb, table1.name,
table1b.IDa, table1b.IDb, table1b.name
from
(select IDa,IDb,name from mytable) table1
inner join
(select IDa,IDb,name from mytable) table1b
ON
table1.IDa = table1b.IDa
and table1.IDb = table1b.IDb
order By table1.IDa
So I'm getting this:
IDa IDb name IDa IDb name
1 1 bob 1 1 public
1 1 bob 1 1 smith
1 2 sally 1 2 jones
2 1 nancy 2 1 dole
But I want to receive this:
IDa IDb name IDa IDb name
1 1 bob 1 1 public
1 2 sally 1 2 jones
2 1 nancy 2 1 dole
I only want the first match for the IDa+IDb combination returned.
Based on asker's comment
That would be the oldest entry into the database, it would also be the
same as order by IDa,IDb. It would also be the first match seen in the
returned results
Try this query :
select table1.IDa, table1.IDb, table1.name,
table1b.IDa, table1b.IDb, table1b.name
from
(select IDa,IDb,name from mytable) table1
inner join
(select IDa,IDb,name, ROW_NUMBER() OVER( ORDER BY Ida,IDb) as r from mytable ) table1b
ON
table1.IDa = table1b.IDa
and table1.IDb = table1b.IDb
and table1b.r=1
order By table1.IDa
As per your comments this should work, But Smith and Public has same IDa and IDb values hope it is data issue.
;WITH cte
AS (SELECT rn=Row_number()OVER(partition BY table1b.name ORDER BY table1.IDa, table1.IDb),
table1.IDa AS t1_ida,
table1.IDb AS t1_idb,
table1.name AS t1_name,
table1b.IDa AS t2_ida,
table1b.IDb AS t2_idb,
table1b.name AS t2_name
FROM mytable table1
INNER JOIN mytable table1b
ON table1.IDa = table1b.IDa
AND table1.IDb = table1b.IDb)
SELECT *
FROM cte
WHERE rn = 1

Get element names

I got 4 tables as follows:
tbProjekt
--------------
Id
every Machine has ProjektId which belongs to:
tblMaszyna
--------------
Id
ProjektId
tblElement
--------------
Id
Name
in this table i am associating elements with machines:
tblMaszElem
--------------
Id
IdElem
IdMach
I would like to take those elements - Name from tblElement which belongs to machines which belongs to specified ProjectId. So lets say for ProjectId 10 How can i achieve that?
select e.Name
from tbElement e
inner join tbMaszElem me on me.IdElem = e.Id
inner join tbMaszyna m on m.Id = me.IdMach
inner join tbProject p on p.Id = m.ProjektId
where
p.Id = 10
This should do. This selects the Name column of all entries in the tbElement table which are associated to a machine that's associated to a project where the project ID is 10.
Please check this sample and its comment
select
te.name
from
tblMaszElem tmem
inner join tblElement te on te.id = tmem.IdElem
inner join tblMaszyna tmzy on tmzy.id = tmem.IdMach
--inner join tbProjekt tp on tp.id = tmzy.ProjektId --i think this should be avoidable
where
tp.id = 10

employee attendance structure using 3 table left innerjoins

SELECT b.Device_Person_ID, a.Personal_id, Date1,
CASE WHEN b.Device_Person_id IS NOT NULL THEN 'A' ELSE 'P' END as Emp_Status
FROM Emp_setting a
LEFT OUTER JOIN (SELECT device_person_id, MAX(logDateTime) AS Date1 FROM tempDeviceLogs
GROUP BY device_person_id) b
ON a.personal_id = b.device_person_id
here i joined only two tables but i need to join 3 tables to show employee details with attendance with specific date.
Required output is
employeename device_person_id designation emptype status
'dbo.persons_profile table
[pesonal_id]
,[Emp_Code]
,[Title]
,[First_name]
,[Middle_name]
,[last_name]
,[Father_Husband_Name]
,[Dob]
,[Age]
,[gender]
,[Marital_status]
,[Nationality]
,[bloodGroup]
,[perAddress]
,[PerStreet]
,[PerLocation]
,[PerCity]
,[PerPincode]
,[CorAddress]
,[CorStreet]
,[CorLocation]
,[CorCity]
,[CorPincode]
,[LandlinePhone]
,[cellNo]
,[EmailId]
,[NosofDependendants]
,[Dependendants_details]
,[Emergency_FirstName]
,[Emergency_Middle_name]
,[Emergency_Last_name]
,[Emergency_WithRelation]
,[Emergency_PhoneNo]
,[Emergency_CellNo]
,[Emergency_emailId]
,[Office_PF_ac_no]
,[ESI_ac_no]
,[JoinedDate]
,[Photofile]
,[ReportTo]
,[Brief_Notes]
,[dateofTermination]
,[termination_note]
,[Print_Priority]
,[DeviceEmployeeID]
,[LogsPermitted]
,[Machin_install_id]
,[Designation]
,[Dept]
,[Section]
,[Groups]
,[EmpWorkingTypeT]'
dbo.tempDeviceLogs table
[LogsID]
,[Device_Person_id]
,[Device_id]
,[logDateTime]
,[logVerifyMode]
,[workCodeID]
,[Machin_install_id]
,[data_loaded_dt]
,[Inout]
dbo.Emp_setting table
[Empset_id]
,[personal_id]
,[DesignationID]
,[DivisionID]
,[Emp_status]
,[Emp_TypeId]
,[Dept_Id]
,[Group_Id]
,[NDIVGRP_CODE]
you need to write to join conditions for achieving what you required.
as an example:
SELECT a.<respective>_id, d.<respective>_title, s.<respective>_id
FROM Emp_setting a
INNER JOIN persons_profile s ON a.<respective>_id = s.<respective>_id
INNER JOIN Emp_setting d ON a.<respective>_id = d.<respective>_id
INNER JOIN tempDeviceLogs b ON s.<respective>_id = b.<respective>_id

how to group in two tables in SQl server?

I have the following issue :
table # 1 structure :
Requests table for example have 2 columns :
Request_ID Branch_Name
1 xx
2 yy
3 xx
4 xx
5 yy
The second table : Requests_Items for example have the following columns
Request_ID Price
1 100
1 30
1 450
2 10
2 18
So i want my result set to be like :
Branch Name Num_of_Requests Total_Price
xx 3 580
Can you please help
select r.Branch_Name,
count(r.request_id) as Num_of_Requests,
sum(i.price) as Total_Price
from Requests r
left join Requests_Items i on i.Request_ID = r.Request_ID
group by r.Branch_Name
jurgen d was almost there
select r.Request_Id, r.Branch_Name,
COUNT(i.Price) as [Number of Requests],
SUM(i.Price) as [Total]
from Requests r
left join Requests_Items i
on r.Request_Id = i.Request_Id
group by r.Request_Id, r.Branch_Name
select r.Branch_Name, COUNT(ri.Request_ID) as Num_of_Requests, SUM(ri.Price) as Total_Price
from dbo.Requests r
left join dbo.Requests_Items ri
on r.Request_ID = ri.Request_ID
group by r.Branch_Name
Let this is my [Employees] Table
Here is my Dept table
I want the output like this using join and group by
So here is the Query for this-
select max(e.salary) as maxsalary,d.Dept from Employees e inner join DEpt d on e.DeptId=d.id group by e.DeptId,d.Dept
enter code here

Resources