SQL aggregate functions and Group By - sql

Employee
empId
empName
empStoreNum
Invoice
invNo
invAmount
empId
I have two tables above Employee and Invoice. I would like to setup a query to retrieve employee names, employee store numbers, and the total sales for each employee. I have issue a query below and it works but I was not able to retrieve employee store number.
SELECT Emp.empName, Sum(Inv.invAmount) AS totalSales
FROM Invoice AS Inv INNER JOIN Employee AS Emp ON Inv.empId = Emp.empId
GROUP BY Emp.empName
If I add Emp.empStoreNum to the SELECT I get the following error: “You tried to execute a query that does not include the specified expression ‘empStoreNum’ as part of an aggregate function.” How can modify the query to get employee store number also?

All non-aggregate columns in the select-list must be listed in the GROUP BY clause (unless you're using MySQL, which plays by a very different set of rules, or unless you are using a sufficiently recent version of PostgreSQL, which is able to deduce functional dependencies).
SELECT Emp.empName, Emp.empStoreNum, Sum(Inv.invAmount) AS totalSales
FROM Invoice AS Inv INNER JOIN Employee AS Emp ON Inv.empId = Emp.empId
GROUP BY Emp.empName, Emp.empStoreNum

Try adding empStoreNum to GROUP BY
SELECT Emp.empName, Emp.empStoreNum, Sum(Inv.invAmount) AS totalSales
FROM Invoice AS Inv INNER JOIN Employee AS Emp ON Inv.empId = Emp.empId
GROUP BY Emp.empName, Emp.empStoreNum

Add that second column to your group by

Related

How to use count and order by with inner join in mysql?

employee table
department table
How to display department name and number of employees working for that department.
My SQL code:
SELECT department.dname , employee.count(*)
FROM employee
INNER JOIN department
ON dno=dnumber
ORDER BY department.dname;
The correct syntax is:
select d.dname, count(*)
from employee e inner join
department d
on d.dno = e.dnumber
group by d.dname
order by d.dname;
Notes:
You are describing an aggregation query with one row per department. That suggests GROUP BY.
Table aliases make the query easier to write and to read.
Qualify all column names. I have to guess what table dno comes from. There should be no reason to guess.

How to obtain all the tuples after a certain date in sql?

I have to obtain the male employee with highest number of requests in the second half of April 2014.
I have these tables:
Employee (EmployeeID, firstName, LastName, gender)
Workplace (CompanyID, EmployeeID, CompanyName)
Extras (ExtraID, CompanyID, Requests, Description, Date)
Extras.Requests is a string, not numerical.
My SQL attempt looks like this:
SELECT
Employee.FirstName, Employee.LastName,
SUM(COUNT(Extras.ExtraID)
FROM
Employee
INNER JOIN
(Workplace
INNER JOIN
Extras ON Workplace.CompanyID = Extras.CompanyID)
ON Workplace.EmployeeID = Employee.EmployeeID
WHERE
Employee.Gender = "male"
AND Extras.Date BETWEEN #4/15/2014# AND #4/30/2014#
SORT BY
SUM(COUNT(Extras.ExtraID) DESC;
LIMIT 1;
I'm not sure if my query is correct or not, thanks in advance.
There are several issues with your querySUM(COUNT(...)) nesting aggregate functions like this isn't permitted
You also need a GROUP BY clause to use aggregation function with non-aggregating columns (which are Employee.FirstName, Employee.LastName in your query).
Sorting is performed by an ORDER BY clause
Your original query includes a nested inner join which is likely to produce unexpected results.
FROM Employee
INNER JOIN(Workplace
INNER JOIN Extras ON Workplace.CompanyID=Extras.CompanyID
) ON Workplace.EmployeeID=Employee.EmployeeID
While nesting joins is allowed it is rarely used, I suggest you avoid it.
I would expect the query to look more like this
SELECT
Employee.FirstName, Employee.LastName, COUNT(Extras.ExtraID)
FROM ((Employee
INNER JOIN Workplace
ON Workplace.EmployeeID = Employee.EmployeeID)
INNER JOIN Extras
ON Workplace.CompanyID = Extras.CompanyID)
WHERE Employee.Gender = "male"
AND Extras.Date BETWEEN #4/15/2014# AND #4/30/2014#
GROUP BY
Employee.FirstName
,Employee.LastName
ORDER BY
COUNT(Extras.ExtraID) DESC;
LIMIT 1;
It's been years since I used access, I think it still wants parentheses in the from clause as I've shown above. In most SQL implementation they are not required, and it is more common for literals to use single quotes e.g. WHERE Employee.Gender = 'male'.

Oracle - Count Function (Orders Sold By each employee)

Having a problem figuring out how to display results that show 2 columns; one being the employee id and the second being the orders sold by that employee.
The 2 tables in question are Employees and Orders. The primary keys in each are called EmployeeID and OrderID. Orders has the foreign key EmployeeID in it. I am assuming I need to use the COUNT function to figure out how many orders there are in total, but the JOIN and finding out how to tie in the employee id with that has lost me.
All I have so far:
SELECT e.employeeid, COUNT(Orders) AS 'Count'
FROM Employees e
JOIN Orders o ON e.Employeeid = o.Employeeid
GROUP BY e.employeeid;
If there is a foreign key in the orders table why even look at employees unless you need something specific from Employees. I would just do something like this.
select employeeid, count(*) from Orders group by employeeid;
Your query is good, the only thing is you cannot count a table, so change COUNT(Orders) to COUNT(o.*) or COUNT(o.OrderID):
SELECT e.employeeid, COUNT(o.OrderID) AS OrderCount
FROM Employees e
JOIN Orders o ON e.Employeeid = o.Employeeid
GROUP BY e.employeeid;
Using a keyword like COUNT as identifier is not recommended, so I change it to OrcerCount, but it will work with 'Count' if you really wanted that.
This query will only give you the employees who have orders (at least one order). If you want to include employees who don't have any order, change JOIN to LEFT JOIN.

How to join one to many tables in Oracle database

I have four tables:
Order, Employee, Supply, Supply_company
Order
------------------
Order_id
Order name
Emp_id
Employee
------------------
Emp_id
Emp_name
Supply
--------------------
Supply_id
Order_id
SupplierName
Supply_company
----------------------
Supply_company_id
Supply_id
Supplier_desc
address
In these 4 tables one employee has more than one order and one order has many supply ID's and for that one supply ID we have one supplier desc. I wanted to display Supplier_desc based on Emp_id. I am getting all the descriptions associated with all orders but I need to get specific desc for specific order, I have tried distinct, listagg, inner join and left outer join and used subquery in where clause but I didn't find any solution.
SELECT
O.EMP_ID,SC.*
FROM
SUPPLY_COMPANY SC
INNER JOIN
SUPPLY S
ON S.Supply_id=SC.Supply_id
INNER JOIN
Order O
ON O.Order_id=S.Order_id
WHERE O.Emp_id=123
Assuming that you have a particular EMP_ID and an ORDER_ID the following query will get you the EMP_NAME and all SUPPLIER_DESCs associated with that employee and order:
SELECT DISTINCT e.EMP_ID, e.EMP_NAME, s.SUPPLIER_DESC
FROM EMPLOYEE e
INNER JOIN ORDER o
ON o.EMP_ID = e.EMP_ID
INNER JOIN SUPPLY s
ON s.ORDER_ID = o.ORDER_ID
INNER JOIN SUPPLY_COMPANY c
ON c.SUPPLY_ID = s.SUPPLY_ID
WHERE e.EMP_ID = your_emp_id AND
o.ORDER_ID = your_order_id
Here we just walk down from EMPLOYEE, through ORDER and SUPPLY, to SUPPLY_COMPANY where the SUPPLIER_DESC can be found, then use the WHERE clause to filter the results down to the particular employee and order we care about - and since you probably don't want repeated rows we put a DISTINCT on the SELECT criteria to tell us we only want a single example of each unique combination. Just replace your_emp_id and your_order_id with the EMP_ID and ORDER_ID values you're interested in. Note that if you supply and EMP_ID and ORDER_ID which do not have anything in common on the EMPLOYEE and ORDER tables you'll get nothing returned by this query.
Best of luck.

sql show current instance

here is the assignment that I had to face:
List the employees who have transferred between departments during their employment. You should show their current department, and the date when the transferred to the current department. This is a pretty tough query. My solution was to use a subquery to determine which employees have been in more than one department, and use that result in the base query.
The problem that I don't know how to display the employee who have been transfered and only once. The way to tell if the employee has been transfered is if in the EmployeeDepartmentHistory table, the employee id has been in more than one record (i.e. employeeID 1 is in both record 1 and record 2 because the person has been in two departments). How would I go about this? Here's what I have as of now:
SELECT EmployeeDepartmentHistory.EmployeeID,Person.Contact.FirstName, Person.Contact.LastName, Department.Name
From HumanResources.Department INNER JOIN
HumanResources.EmployeeDepartmentHistory ON
HumanResources.Department.DepartmentID =
HumanResources.EmployeeDepartmentHistory.DepartmentID INNER JOIN
HumanResources.Employee ON HumanResources.EmployeeDepartmentHistory.EmployeeID
= HumanResources.Employee.EmployeeID INNER JOIN
Person.Contact ON HumanResources.Employee.ContactID = Person.Contact.ContactID
WHERE EmployeeDepartmentHistory.EmployeeID=(SELECT COUNT(HumanResources.EmployeeDepartmentHistory.EmployeeID)
FROM HumanResources.EmployeeDepartmentHistory
WHERE EmployeeDepartmentHistory.EmployeeID = Employee.EmployeeID
Group by EmployeeDepartmentHistory.EmployeeID)
Not sure if I get the requirement correct. Would you want to try HAVING clause at the end?
That is:
HAVING COUNT(EmployeeDepartmentHistory.EmployeeID) = 2
(2 - assuming that the EmployeeDepartmentHistory will contain the current department as well)