Joining same table multiple times - sql

I have 2 tables Person an Department - where each person has multiple departments registered against him.
Person
id|name|dept1|dept2|dept3
1 |Jane|100 |102 |106
Dept
id |Name
100|Accounts
...
102|HR
...
106|Admin
Whats the most elegant sql to display Jane's record as follows:
Jane|Accounts|HR|Admin

Use this. And work on your naming convention to make all column names unique independent of table.
SELECT
Person.id, Person.name, dept1.Name, dept2.Name, dept3.Name
LEFT JOIN Dept dept1 ON dept1.id = Person.dept1
LEFT JOIN Dept dept2 ON dept2.id = Person.dept2
LEFT JOIN Dept dept3 ON dept3.id = Person.dept3

Something like this will let you join the same table multiple times. You just give each join a different alias
SELECT *
FROM Person AS P
INNER JOIN Dept AS D1 ON P.dept1 = D1.id
INNER JOIN Dept AS D2 ON P.dept2 = D2.id
WHERE P.name = 'Jane'
Ideally you would normalise the data in your Person table and have a linking table between Person and Dept e.g. PersonDepartmentLinking (or whatever convention you have for linking table naming conventions), assuming you have any control over the schema and it's possible to add the relationship that way.

You can use STUFF in this case
Select name,
Stuff((Select distinct ', ' + cast(Name as varchar(20))
From #Dept t2
Where t2.Id = t1.Id
FOR XML PATH('')),1,1,'')
From Person t1

The only way that I know is a join for each column.
But if you are in the way of designing the tables, i suggest you to normalize the DB.
If a person need an extra dept column, you need to alter the table to add a new property of person.
For me, 3 entities are needed:
- Person
- Department
- person_department_assignation

Related

Create a additional row from join sql?

I have 2 tables: Person and House with 1-n relation.
I want to the result return as picture below:
Row always have a Person column with a null House column.
Thanks.
you can use unionall to join the result set with person table something like
select p.name,h.name as housename from person p join house h on p.id=h.personid
union all (select name,null from person)
order by name,housename

SQL JOIN to get the compare two values/row from table "A" and the same row from table "B"

I have two tables with the following rows
Table A (transaction)
Order Seller Customer
1 300 500
Table B (Persons)
PersonID FullName
300 Peter White
500 Scott Bold
I want a result like this
Order Seller Customer FullName (Seller) FullName (customer)
1 300 500 Peter White Scott Bold
I've tried multiple things however which makes more sense is a join a table twice, however I'm getting:
Ambiguous column name
This is SQL Server 2019.
Basically I'm looking to retrieve info from the same table instead of creating additional tables. Is that possible? If yes, how do you do? Thank you in advance.
As #jarlh wrote in comment:
select t.order, t.seller, t.customer, sel.fullname, cust.fullname
from transaction t
join persons sel -- sel is an alias to persons table
on sel.personid = t.seller
join persons cust
on cust.personid = t.customer;
Query with join will return the result as long as both seller and customer exist in persons table -- here it should as source table names transactions :).
I have another form of query it still join table B twice.
This is archaic syntax which I don't recommend but for beginner know the concept of JOIN:
select t.*,B.FullName as FullName (customer) from
(
select A.Order,A.Seller,A.Customer,B.FullName as FullName(Seller)
from A,B where A.Seller=B.PersionID
) t, B where t.Customer=B.PersionID
The proper way of JOIN:
select t.*,B.FullName as FullName (customer) from
(
select A.Order,A.Seller,A.Customer,B.FullName as FullName(Seller)
from A JOIN B ON A.Seller=B.PersionID
) t JOIN B ON t.Customer=B.PersionID
Hoping this can help you.

SQL Server : replace several instances of userID with username

I may be overthinking this but I have not managed to figure it out or find a solution, so I'm hoping for a pointer in the right direction. I tried using the Select ColumnA AS Column B etc but it's not doing what I want.
I have 2 tables, scenario examples below
Table 1 (Vehicle)
VehicleID (001)
VehicleMake (Ford)
VehicleModel (Falcon)
VehicleExCleanEmpID (005)
VehicleIntCleanEmpID (003)
Table 2 (Employee)
EmpID (005)
EmpName (Dave)
The scenario being that a vehicle is cleaned internally or externally by any one of a pool of employees shown by the relevant ID in the Vehicles table.
I want to show in a query VehicleID, InsideCleanName, ExternalCleanName rather than showing the employee's ID.
So end up with results similar to this
VehicleID InsideCleanName ExternalCleanName
------------------------------------------------
001 Bob Dave
002 Sue Dave
003 John Sid
Thanks for any tips and or help
THat seems like a pretty simple query with two inner joins to the Employee table - something like this:
SELECT
v.VehicleId,
InsideCleanName = e1.EmpName,
ExternalCleanName = e2.EmpName
FROM
dbo.Vehicle v
INNER JOIN
dbo.Employee e1 ON v.VehicleIntCleanEmpId = e1.EmpID
INNER JOIN
dbo.Employee e2 ON v.VehicleExCleanEmpId = e2.EmpID
Joining to the Employee e1 table is giving you the employee who was responsible for the inside cleaning, while joining a second time, to Employee e2 gives you the one responsible for the external cleaning.
Join the two table with EmpId and select the columns you want similar to the code below:
select column1, column2 from table1 inner join table2 on table1.EmpId = table2.EmpId

select distinct out of distinct

I have two table one has employees goals and the other has list of employees. i have to match one to another. Seems easy to do. but in the employee table employees can be entered more than once with more than one way of spelling their names. How can I pick only one name for each ID, it really doesn't matter which one I pick.
this is the code i used:
select distinct (etar.EmplKey ), emp.EmplFullName
FROM EmployeeTarget etar
inner join DimEmployee emp on emp.emplkey = etar.emplkey
inner join dimbranch br on br.BranchId = etar.BranchId
where etar.BranchId = 8
this is the results i get:
EmplKey EmplFullName
100260 Ida Patton
101488 Don Sheppard
101488 Donald Sheppard
101489 Teresa Coverdale
103121 Harjinder Aujla
How can I have that Don Sheppard guy listed only once?
The easiest way is to do aggreagtion:
select etar.EmplKey, min(emp.EmplFullName)
FROM EmployeeTarget etar
inner join DimEmployee emp on emp.emplkey = etar.emplkey
inner join dimbranch br on br.BranchId = etar.BranchId
where etar.BranchId = 8
group by etar.EmplKey

Combining tables in SQL/QlikView

Is it possible to combine 2 tables with a join or similar construct so that all non matching field in one group. Some thing like this:
All employees with a department name gets their real department and all with no department ends up in group "Other".
Department:
SectionDesc ID
Dep1 500
Dep2 501
Employee:
Name ID
Anders 500
Erik 501
root 0
Output:
Anders Dep1
Erik Dep2
root Other
Best Regards Anders Olme
What you are looking for is an outer join:
SELECT e.name, d.name
FROM employee e
LEFT OUTER JOIN departments d ON e.deptid = d.deptid
This would give you a d.name of NULL for every employee without a department. You can change this to 'Other' with something like this:
CASE WHEN d.name IS NULL THEN 'Other' Else d.name END
(Other, simpler versions for different DBMSs exist, but this should work for most.)
QlikView is a bit tricky, as all joins in QlikView are inner joins by default. There is some discussion in the online help about the different joins, short version is that you can create a new table based on different joins in the script that reads in your data. So you could have something like this in your script:
Emps: SELECT * FROM EMPLOYEES;
Deps: SELECT * FROM DEPARTMENTS;
/* or however else you get your data into QlikView */
EmpDep:
SELECT Emps.name, Deps.name
FROM EMPS LEFT JOIN Deps
In order for this join to work the column names for the join have to be the same in both tables. (If necessary, you can construct new columns for the join when loading the base tables.)