Average from two different table using group by - group-by

I have a table Called DEPARTMENTS with Columns:
DepartmentID
DepartmentName
Another table Called EMPLOYEE with Columns:
EmployeeID
DepartmentID
EmployeeName
Salary
I need a JOIN query with possibly Group By to display DepartmentName and AVERAGE Salary
Basically the Output should display:
DepartmentX 40000
DepartmentY 15000
DepartmmentZ 35000

You need to use AVG() aggregate function with JOIN between two tables like
SELECT d.DepartmentName,
AVG(e.Salary) as average_salary
FROM Employee e
JOIN DEPARTMENTS d ON e.DepartmentID = d.DepartmentID
GROUP BY e.DepartmentID;
(OR) get the average first and then perform a JOIN like
SELECT d.DepartmentName,
xx.average_salary
FROM DEPARTMENTS d
JOIN (
select DepartmentID, AVG(Salary) as average_salary
from Employee
GROUP BY DepartmentID) xx ON xx.DepartmentID = d.DepartmentID;

Related

Using Count Function and Percentage of Count Total in One Select Statement

I have three data tables Employees, Departments, and Locations.
I want to show the total number of employees in each state and what percentage of the employees are located in that each state. The Employees table and the Departments table have one identical column called Department_ID, and the Departments table and the Locations table have one identical column called Location_ID. Here's what I wrote for my code:
select l.state_province e.count(*) as "Employees in State",
e.count(*)*100/sum(e.count(*)) over ()
from employees e
full outer join departments d on e.department_id = d.department_id
full outer join locations l on l.location_id = d.location_id
order by l.state_province;
However, the error "from keyword not found where expected" shows up when I run the code. How do I fix it?
You need group by. And regular joins should be fine:
select l.state_province, count(*) as "Employees in State",
count(*) * 100/sum(count(*)) over ()
from employees e join
departments d
on e.department_id = d.department_id join
locations l
on l.location_id = d.location_id
group by l.state_province
order by l.state_province;

Biggest sale of every employee on Northwind?

I'm trying to list the biggest sale of each employee on Northwind database, and so far the best I could do is this;
select top (select count(EmployeeID) from Employees)
max(Quantity*OrderDetails.UnitPrice) TotalSale, FirstName+' '+LastName Name, ProductName from Orders
left join OrderDetails
on
OrderDetails.OrderID=Orders.OrderID
left join Employees
on
Orders.EmployeeID=Employees.EmployeeID
left join Products
on
OrderDetails.ProductID=Products.ProductID
group by FirstName,LastName, ProductName
order by TotalSale desc
But even though I used the group by I get repeated records;
TotalSale Name ProductName
15810,00 Andrew Fuller Côte de Blaye
15810,00 Nancy Davolio Côte de Blaye
10540,00 Robert King Côte de Blaye
10540,00 Anne Dodsworth Côte de Blaye
10540,00 Margaret Peacock Côte de Blaye
9903,20 Janet Leverling Thüringer Rostbratwurst
8432,00 Steven Buchanan Côte de Blaye
7905,00 Janet Leverling Côte de Blaye
7427,40 Andrew Fuller Thüringer Rostbratwurst
Warning: Null value is eliminated by an aggregate or other SET operation.
(9 row(s) affected)
So I have 9 employees and I used top function for that but the employees are not unique, I also tried to use distinct function but it didn't work either.
So I would appreciate a hand please!
Your issue is that you also group by productname. So you will get max sales per employee and per product name.
What you can do is, drop the product name in group by, in this case you will see max total sales only per employee.
select max(Quantity*OrderDetails.UnitPrice) TotalSale, FirstName+' '+LastName Name
from Orders
left join [Order Details] as OrderDetails on OrderDetails.OrderID=Orders.OrderID
left join Employees on Orders.EmployeeID=Employees.EmployeeID
left join Products on OrderDetails.ProductID=Products.ProductID
group by FirstName,LastName
order by TotalSale desc
In case you want to see the product name as well, you can encapsulate your query in a subquery and create a rownum based on employee name and order by total sales. You can select rows with rownum 1 in the outer query. Use rank function in case you need to show all occurances of product names.
SELECT TotalSale, Name, ProductName
FROM
(
select max(Quantity*OrderDetails.UnitPrice) TotalSale
,FirstName + ' ' + LastName Name
,ProductName
,Rnk = Rank() OVER(PARTITION BY Employees.EmployeeId ORDER BY MAX(Quantity*OrderDetails.UnitPrice) DESC)
from Orders
left join [Order Details] as OrderDetails on OrderDetails.OrderID=Orders.OrderID
left join Employees on Orders.EmployeeID=Employees.EmployeeID
left join Products on OrderDetails.ProductID=Products.ProductID
group by FirstName,LastName, Employees.EmployeeId, ProductName
) as sub
where sub.Rnk = 1
order by Name

Removing duplicate rows from relation

I have the following code which produces a relation:
SELECT book_id, shipments.customer_id
FROM shipments
LEFT JOIN editions ON (shipments.isbn = editions.isbn)
LEFT JOIN customers ON (shipments.customer_id = customers.customer_id)
In this relation, there are customer_ids as well as book_ids of books they have bought. My goal is to create a relation with each book in it and then how many unique customers bought it. I assume one way to achieve this is to eliminate all duplicate rows in the relation and then counting the instances of each book_id.
So my question is: How can I delete all duplicate rows from this relation?
Thanks!
EDIT: So what I mean is that I want all the rows in the relation to be unique. If there are three identical rows for example, two of them should be removed.
This will give you all the {customer,edition} pairs for which an order exists:
SELECT *
FROM customers c
JOIN editions e ON (
SELECT * FROM shipments s
WHERE s.isbn = e.isbn
AND s.customer_id = c.customer_id
);
The duplicates are in table shipments. You can remove these with a DISTINCT clause and then count them in an outer query GROUP BY isbn:
SELECT isbn, count(customer_id) AS unique_buyers
FROM (
SELECT DISTINCT isbn, customer_id FROM shipments) book_buyer
GROUP BY isbn;
If you want a list of all books, even where no purchases were made, you should LEFT JOIN the above to the list of all books:
SELECT isbn, coalesce(unique_buyers, 0) AS books_sold_to_unique_buyers
FROM editions
LEFT JOIN (
SELECT isbn, count(customer_id) AS unique_buyers
FROM (
SELECT DISTINCT isbn, customer_id FROM shipments) book_buyer
GROUP BY isbn) books_bought USING (isbn)
ORDER BY isbn;
You can write this more succinctly by joining before counting:
SELECT isbn, count(customer_id) AS books_sold_to_unique_buyers
FROM editions
LEFT JOIN (
SELECT DISTINCT isbn, customer_id FROM shipments) book_buyer USING (isbn)
GROUP BY isbn
ORDER BY isbn;

T-SQL filter on external join

Using the schema below, write a query which lists the total value of all sales for customers who bought an item from a sales person with the same middle initial as them. Your query should return a single result.
The quantity and price columns are both ints.
The Sales - Employee link is on EmployeeID - SalesPersonID.
Something like this should work:
select sum(s.Quantity * p.Price) as TotalSales
from Sales s
join Products p on s.ProductID = p.ProductID
join Customers c on s.CustomerID = c.CustomerID
join Empleyees e on s.SalesPersonID = e.EmployeeID
where c.MiddleInitial = e.MiddleInitial

Postgresql-Select one row from table where value in many table matches?

I have two tables, call them a and b, where a is related to b in a one-to-many relationship. I would like to select any rows from table a where any of the many related records in table b match a criteria. A basic join doesn't work, because that will return one result for each row in table b that matches - I just want one result for each row in table a with one or more related records matching.
For simplified example, say I have a table Departments and related table Employees, where each employee has one department, but each department obviously can have multiple employees. I want a query that will give me one row per department that has one or more employees matching a given criteria - say the departments that have one or more employees that have earned "employee of the month". How would I do this? Thanks.
SELECT * FROM department d
WHERE EXISTS (
SELECT * FROM employee e
JOIN badges b ON b.person_id = e.person_id AND b.badge = 'EotM'
WHERE e.dep_id = d.dep_id
AND e.gender = 'F'
);
select distinct on (d.id)
d.name
from
department d
inner join
employee e on d.id = e.department_id
where e.age between 60 and 65
How to order it by any column:
select *
from (
select distinct on (d.id)
d.*
from
department d
inner join
employee e on d.id = e.department_id
where e.age between 60 and 65
) s
order by name
Sounds like a job for a subquery. Something like: Select * from dept where id in (select deptID from Emp where wasEOTM = true); ought to do the job.