Excluding duplicates - sql

The query I'm stuck on is supposed to list the number of customers the employees sold to and count the customers only once, even if they had multiple sales. I'm very new to this and cannot seem to figure it out. Any help is greatly appreciated!
select count(distinct o.customerid) 'Number of Customers',
e.EmployeeID 'Employee ID', e.LastName, e.firstname
from employees e
full join Orders o
on e.EmployeeID = o.employeeid
group by o.CustomerID, e.EmployeeID, e.LastName, e.firstname
order by e.employeeid, o.customerid asc
Here are the results I'm getting, and it indicates how the list is coming up with a list of results. I'm trying to get the total number in one field. Hope this makes more sense?

You have customerid in your group by clause - so it will produce one row per customerid - remove it (also from the orderby) and perhaps you will have the result you need
select count(distinct o.customerid) 'Number of Customers',
e.EmployeeID 'Employee ID', e.LastName, e.firstname
from employees e
full join Orders o
on e.EmployeeID = o.employeeid
group by e.EmployeeID, e.LastName, e.firstname
order by e.employeeid

Related

SQL to find the maximum number in a grouped column result

I want to display only the highest "TotalSales" after grouping by empname column.
Please below is my SQL statement.
select e.empname as "EmployeeName", sum(p.price) as "TotalSales"
from employees e
join orders o on e.employee_id = o.empid
join products p on o.orderID = p.orderID
group by e.empname
order by TotalSales desc

Which employee has processed most orders?

I was trying to do my exercise to get an answer to this question,
--Which employee has processed most orders?
following the table below;
and in SQL the query became this monster
select e.employeeid, e.lastname, count(*) as 'aantal' from employee e
join orders o on e.EmployeeID = o.EmployeeID group by e.EmployeeID,
e.LastName having count(*) = (
select top 1 count(*) as 'aantal' from employee e
join orders o on e.EmployeeID = o.EmployeeID
group by e.FirstName
order by count(*) desc
)
my question is, is there really no other ways to get an answer from this:
select e.employeeid, e.lastname, count(*) as 'aantal' from employee
join orders o on e.EmployeeID = o.EmployeeID
group by e.EmployeeID, e.LastName
and then just find a maximum of these table??
like: max(and here query)
You probably can try this:
select e.employee_id, e.title, count(o.order_id) as c from orders o join employees e on e.employee_id = o.employee_id group by e.employee_id, e.title order by c desc;
Answer to my question.
This is just impossible in SQL
https://www.youtube.com/watch?v=8hyCpyhj8Jc&ab_channel=DaveSullivan

Rewrite SQL Code Using a Join Instead of Subquery

I'm having trouble visualizing how subqueries would look in the form of joins instead. In particular, the following SQL:
SELECT DISTINCT e.EmployeeID, e.LastName, e.FirstName
FROM Employees e
INNER JOIN Orders o ON e.EmployeeID = o.EmployeeID
WHERE EXISTS
(
SELECT c.Country
FROM Customers c
WHERE c.Country = e.Country
)
It would greatly be appreciated if I could receive some tips on what to do when I want to turn a statement with a subquery into a join instead.
You need to be careful about duplicates, but the transformation for EXISTS is quite direct:
SELECT DISTINCT e.EmployeeID, e.LastName, e.FirstName
FROM Employees e INNER JOIN
Orders o
ON e.EmployeeID = o.EmployeeID INNER JOIN
(SELECT DISTINCT c.Country
FROM Customers c
) c
ON c.Country = e.Country
This looks clean. In fact, it is not:
SELECT DISTINCT e.EmployeeID, e.LastName, e.FirstName
FROM Employees e
JOIN Orders o ON o.EmployeeID = e.EmployeeID
JOIN Customers c ON c.Country = e.Country
;
The point is that if there are more than one matching rows for orders and Customers, these will all cause a seperate copy of the Employee record to be merged. These will later have to be suppressed by theDISTINCT(the optimiser might catch this, or it might not)
The point is: you dont need a distinct, since you are only selecting columns from employee:
SELECT e.EmployeeID, e.LastName, e.FirstName
FROM Employees e
WHERE EXISTS(
SELECT * FROM Orders o
WHERE o.EmployeeID = e.EmployeeID
)
AND EXISTS(
SELECT * FROM Customers c
WHERE c.Country = e.Country
);
Or,in a more or less ugly style:
SELECT e.EmployeeID, e.LastName, e.FirstName
FROM Employees e
WHERE EXISTS(
SELECT c.Country
FROM Orders o
JOIN Customers c
ON o.EmployeeID = e.EmployeeID
AND c.Country = e.Country
);

SQL Join condition clause

I have database with as diagram shows (see picture below)
My task is to show total value of orders handled by each Employees.
I have SQL statement:
SELECT e.FirstName,
e.LastName,
SUM(od.Quantity * od.UnitPrice * (1-od.Discount))
FROM Orders AS o
JOIN Employees AS e
ON o.EmployeeID = e.EmployeeID
JOIN [Order Details] AS od
ON o.OrderID = od.OrderID
GROUP BY e.FirstName,e.LastName
I have problem with further steps. I need to limited results only for those employees which:
A) Have employees under them
B) Don't have any employees under them
I know It concern field ReportsTO in Employees table, but I don't know how get proper SQL clause. I am supposed to do with "EXISTS" or self-join ?
Thank You.
Yes, Just use Exists.
Where Exists(Select 1 from Employees where ReportsTo = e.EmployeeId)
Use a self join to try to find someone reporting to him
SELECT e.FirstName,
e.LastName,
SUM(od.Quantity * od.UnitPrice * (1-od.Discount))
FROM Orders AS o
INNER JOIN Employees AS e
ON o.EmployeeID = e.EmployeeID
LEFT JOIN Employees as under -- self join
ON e.EmployeeID = under.ReportTo
INNER JOIN [Order Details] AS od
ON o.OrderID = od.OrderID
GROUP BY e.FirstName,e.LastName
HAVING MAX(under.ReportTo) IS NULL -- If doesnt find a match mean no one subordinate
-- MAX(under.ReportTo) IS NOT NULL -- mean have at least one subordinate
With a self join you can potentially create duplicates which would be difficult to debug due to the GROUP BY. EXISTS with a correlated sub query in the WHERE clause would be how I would accomplish this.
SELECT *
FROM Employees e
WHERE EXISTS(
SELECT 1
FROM Employees _e
WHERE _e.ReportsTo = e.EmployeeID)
In your query:
SELECT e.FirstName,
e.LastName,
SUM(od.Quantity * od.UnitPrice * (1-od.Discount))
FROM Orders AS o
JOIN Employees AS e
ON o.EmployeeID = e.EmployeeID
JOIN [Order Details] AS od
ON o.OrderID = od.OrderID
WHERE /*NOT*/ EXISTS(
SELECT 1
FROM Employees _e
WHERE _e.ReportsTo = e.EmployeeID)
GROUP BY e.FirstName,e.LastName

SQL join related question

I am having trouble with a SQL join question.
I have a table EMPLOYEE with EmpID, FirstName, LastName, Email, Phone
I have another table OTHERNAME with 2 fields "Name" & "OtherName".
This table contains lookup values such as "James", "Jim"; "Thomas", "Tom"; "Steven", "Steve".
I want to write a query which will return rows
EmpID, FirstName, LastName, Email, Phone, OtherName
where Employee.Firstname = OTHERName.Name
Select e.EmpID, e.FirstName, e.LastName, e.Email, e.Phone, o.OtherName
From Employee e
Left Outer Join OtherName o on e.FirstName = o.Name
From your comments it sounds like you actually want an outer join.
(From Comments) An outer join would return all employees, along with an Othername if there is one, otherwise Othername would be a null value which you could handle in code. An inner join limits the results to only employees with a matching record.
try this:
SELECT
e.EmpID
CASE
WHEN o.OtherName IS NOT NULL THEN OtherName
ELSE e.FirstName
END AS FirstName
,e.LastName
,e.Email
,e.Phone
,o.OtherName
FROM Employee e
LEFT OUTER JOIN OtherName o ON e.FirstName = o.Name
select e.EmpID, e.FirstName, e.LastName, e.Email, e.Phone, o.OtherName
from employee e,othername o
where e.FirstName=o.name
SELECT E.EmpId,
E.FirstName,
E.LastName,
E.Email,
E.Phone,
O.OtherName
FROM EMPLOYEE E
INNER JOIN OTHERNAME O
ON E.FirstName = O.Name
SELECT E.EmpID, E.FirstName, E.LastName, E.Email, E.Phone, O.OtherName
FROM Employee E
INNER JOIN Othername O
ON E.Firstname = O.Name
Should do the trick
Or, if you want all results, even those without "other name" values.
SELECT E.EmpID, E.FirstName, E.LastName, E.Email, E.Phone, O.OtherName
FROM Employee E
LEFT OUTER JOIN Othername O
ON E.Firstname = O.Name
You may use following SQL Command
SELECT EMPLOYEE.EmpID,
EMPLOYEE.FirstName,
EMPLOYEE.LastName,
EMPLOYEE.Email,
EMPLOYEE.Phone,
OTHERNAME.OtherName FROM EMPLOYEE INNER JOIN OTHERNAME ON EMPLOYEE.FirstName = OTHERNAME.Name