Sql server: Join two tables and select multiple column values with subquery - sql

Table OpenPO
Shopping_Cart_No
Goods_Recipient_Emp_ID
accassgnmtownerid
1001958413
160213
65658
1001661570
61875
61855
Table Employee
employee_number
Email
160213
Quentin_Walker#gmail.com
61875
Mihaela_Balseanu#gmail.com
65658
siva#gmail.com
61855
mohan#gmail.com
I have these two tables, both are linked by the employee_number column.
I want to display data as shown below .
Expected result
Goods_Recipient_Email
Goods_Recipient_Emp_ID
accassgnmtownerid
accassgnmtownerid_Email
Quentin_Walker#gmail.com
160213
65658
siva#gmail.com
Mihaela_Balseanu#gmail.com
61875
61855
mohan#gmail.com
Tried with left join and able to compare and select only one email column Goods_Recipient_Emp_ID or op.accassgnmtownerid
SELECT
op.Goods_Recipient_Emp_ID, op.accassgnmtownerid,
te.Email AS accassgnmtownerid_Email
FROM
OpenPO op
LEFT JOIN
Employee te ON te.Employee_Number = op.Goods_Recipient_Emp_ID
Tried with subquery for accassgnmtownerid_Email, but it didn't work out.
Can we apply subquery for accassgnmtownerid_Email or is there any other solution?

You need to join the table employee twice, using two different aliases.
For example:
select
r.email as Goods_Recipient_Email,
o.Goods_Recipient_Emp_ID,
o.accassgnmtownerid,
a.email as accassgnmtownerid_Email
from openpo o
join employee r on r.employee_number = o.Goods_Recipient_Emp_ID
join employee a on a.employee_number = o.accassgnmtownerid

Other than joining the tables for each Email, you can also use a correlated subquery for each, such as
select
(select Email from Employee e where e.employee_number = po.Goods_Recipient_Emp_ID) Goods_Recipient_Email,
po.Goods_Recipient_Emp_ID,
po.accassgnmtownerid,
(select Email from Employee e where e.employee_number = po.accassgnmtownerid) accassgnmtownerid_Email
from OpenPO po;

Related

Single SQL query on many to many relationship using join

I have a simple database with few tables (and some sample columns)
Employee (ID, Title, Content)
Project (ID, Title)
ProjectEmployee(ID ,EMPLOYEE_ID,PROJECT_ID)
Need to find employee's whose don't have any project using join query
I am able to do it using subquery
select * from employee
where id not in (select id from project_employee);
The LEFT JOIN with NOT NULL give you the expected results.
select e.*
from employee e
LEFT JOIN project_employee pe on pe.id = e.id
where pe.id is not null;
This would be best implemented using not exists, joining is not the correct solution if you do not need to return any columns from the joined table.
select *
from employee e
where not exists (select * from project_employee pe where pe.id = e.id)

SQL Joins and Corelated subqueries with column data

I am facing an issue in terms of understanding the joins. Lets say for an example we have two tables employee and sales and now I have a query where we have sales of an employee using the id of the employee
select e.employeename
,s.city
,SUM(s.sales)
from employee e
left join (select sales,eid from sales) s on s.eid = e.id
group by 1,2
I'd like to understand why s.city wasn't showing up? and also would like to understand what is this concept called? Is it co related sub queries on Joins? Please help me down over here.
select
e.employeename
,s.city
,SUM(s.sales)
from employee e
left join (select sales,eid,city from sales) s on s.eid = e.id
group by 1,2
in the left join above you have to add city as well. The query Imagine select sales,eid,city from sales is a table itself and then from this table you are selecting city (your second column s.city) this will run error as your table doesn't have a city column yet.
It is much easier to use CTE (common table expressions than CTE's) You can also do the above question as
select
e.employeename
,s.city
,SUM(s.sales)
from employee e
left join sales as s
on e.id = s.id
group by 1,2
here I have added e.id = s.id instead of s.id = e.id it is better to reference the key of the main table first.
you could use CTE (although used when you have to do a lot of referencing but you can see how it works):
With staging as (
select
e.employeename
,s.city
,s.sales
from employee e
left join sales as s
on e.id = s.id
),
sales_stats as (
select
staging.employeename,
staging.city,
sum(staging.sales)
from staging
group by 1,2
#here you will select from staging again consider staging as a separate table so you will have to have all the columns in the staging that you want to use further. Also you will have to reference columns using staging.x
)
select * from sales_stats
-- here you could have combined the steps but I wanted to show you how cte works, Hope this works for you

Is it possible to join a table to itself

I have a query that joins two tables together. In table O I have an employee ID, which I join to the HR table to retrieve the employee name:
inner join hr AS hr on o.syscreator = hr.res_id
Also on the HR table is the employees manager, but the value is only the employee ID of the manager. Therefore to retrieve the full name of the manager, would I need to use a self join? I could only find examples of self join using the FROM table, in this case it's the join table.
select o.ordernr,
o.refer,
o.orddat,
o.afldat,
o.magcode,
o.user_id,
o.status,
o.represent_id,
o.crdnr,
o.ord_debtor_name,
o.ord_AddressLine1,
ord_PostCode,
ord_City,
ord_StateCode,
o.ord_landcode,
o.ord_Phone,
o.ord_contactperson,
o.ord_contactemail,
o.syscreated,
h.fullname AS RepName,
h.repto_id AS ManagerID
from order o
inner join humres AS hr on o.syscreator = hr.res_id
Any help would be appreciated.
You can sure bring the same table twice - you just need to use a different alias.
I think that you want:
select
o.ordernr,
...,
h.fullname AS RepName,
h.repto_id AS ManagerID,
hr_mgr.fullname as MgrName
from order o
inner join humres AS hr on o.syscreator = hr.res_id
inner join humres AS hr_mgr on hr_mgr.res_id = hr.repto_id

Query to Id referencing to an 'Id' to the same table

I have a table AMZ_EMPLOYEE_DETAILS with Employee Id, Employee Name and Supervisor1 and Supervisor 2. The Supervisors are employee itself but represented by their name.
My task was to replace the Supervisor names with their Ids.
I have used the following query to obtain the solution but it uses sub-queries and the query does look optimized. For this I have also made a dimension table with all the Id and Employee Names ,table AMZ_EMPLOYEE
SELECT S1.ID, S1.EMP_NAME, S1.SUPER_1_NEW, ZZ.ID AS SUPER_2_NEW
FROM
(SELECT A.ID,A.EMP_NAME,A.SUPER_1,A.SUPER_2,Z.ID AS SUPER_1_NEW
FROM AMZ_EMPLOYEE_DETAILS A
LEFT JOIN
AMZ_EMPLOYEE Z
ON A.SUPER_1 = Z.EMP_NAME ) S1
LEFT JOIN
AMZ_EMPLOYEE ZZ
ON S1.SUPER_2 = ZZ.EMP_NAME
ORDER BY 1
The following is the expected output.
The logic to use two self-LEFT JOIN is correct. You don't need to use subqueries though. Consider:
SELECT a.id, a.emp_name, a1.id, a2.id
FROM amz_employee_details a
LEFT JOIN amz_employee a1 ON a1.emp_name = a.super_1
LEFT JOIN amz_employee a2 ON a2.emp_name = a.super_2

Joining two tables with specific columns

I am new to SQL, I know this is really basic but I really do not know how to do it!
I am joining two tables, each tables lets say has 5 columns, joining them will give me 10 columns in total which I really do not want. What I want is to select specific columns from both of the tables so that they only show after the join. (I want to reduce my joining result to specific columns only)
SELECT * FROM tbEmployees
JOIN tbSupervisor
ON tbEmployees.ID = tbSupervisor.SupervisorID
The syntax above will give me all columns which I don't want. I just want EmpName, Address from the tblEmployees table and Name, Address, project from the tbSupervisor table
I know this step:
SELECT EmpName, Address FROM tbEmployees
JOIN tbSupervisor
ON tbEmployees.ID = tbSupervisor.SupervisorID
but I am not sure about the supervisor table.
I am using SQL Server.
This is what you need:
Select e.EmpName, e.Address, s.Name, S.Address, s.Project
From tbEmployees e
JOIN tbSupervisor s on e.id = SupervisorID
You can read about this on W3Schools for more info.
You can get columns from specific tables, either by their full name or using an alias:
SELECT E.EmpName, E.Address, S.Name, S.Address, S.Project
FROM tbEmployees E
INNER JOIN tbSupervisor S ON E.ID = S.SupervisorID
You can use the table name as part of the column specification:
SELECT tbEmployees.EmpName, tbEmployeesAddress, tbSupervisor.Name,
tbSupervisor.Address, tbSupervisor.project
FROM tbEmployees
JOIN tbSupervisor
ON tbEmployees.ID = tbSupervisor.SupervisorID
SELECT employees.EmpName, employees.Address AS employeer address,
supervisor.Name, supervisor.Address AS supervisor address,supervisor.project
FROM tbEmployees
AS employees
JOIN tbSupervisor
AS supervisor
ON
employees.ID = supervisor.SupervisorID
You need to learn about aliases. They will make your queries more maintainable. Also, you should always use aliases when referencing columns, so your query is clear about what it is doing:
SELECT e.EmpName, e.Address, s.name, s.address as SupervisorAddress
FROM tbEmployees e JOIN
tbSupervisor s
ON e.ID = s.SupervisorID;
Note that I also renamed the second address so its name is unique.
Specify the table name and field name in your selection
SELECT tbEmployees.EmpName,
tbEmployees.Address,
tbSupervisor.[column name]
FROM tbEmployees
JOIN tbSupervisor ON tbEmployees.ID = tbSupervisor.SupervisorID
SELECT product_report.*,
product.pgroup
FROM `product_report`
INNER JOIN product
ON product_report.product_id = product.id
WHERE product.pgroup = '5'
ORDER BY product.id DESC