Need assistance with basic sql query - sql

I was doing some exercises for practice and have a small problem with my query.
My initial code is below. The problem is I am getting the wrong answer in the final column/
The question : a query to find out the total attributed sales to each sales person for all SalesOrders placed in 2008. Use the TotalDue of the orders to find the sales amounts and the SalesPersonID to find the sales person to attribute. E.g. SalesOrderID 43659 should be attributed to SalesPersonID 279.
SELECT DISTINCT p.BusinessEntityID,p.FirstName,p.LastName, t.TotalDue
FROM Person.Person p,Sales.SalesPerson s,Sales.SalesOrderHeader t
WHERE p.BusinessEntityID = s.BusinessEntityID
Here is the image of my ERD http://www.2shared.com/photo/h2-jMQyP/AdventureWorks2008.html .

This looks like the ideal example of using the GROUP BY clause.
Try the following query:
select p.BusinessEntityID, p.FirstName, p.LastName, sum(t.TotalDue) as TotalDue
from Person.Person p
join Sales.SalesPerson s on p.BusinessEntityID = s.BusinessEntityID
join Sales.SalesOrderHeader t on t.BusinessEntityID = s.BusinessEntityID
where year(t.OrderDate) = 2008
group by p.BusinessEntityID, p.FirstName, p.LastName

if you want totaldue made in 2008 you have to give one more condition for this year part
SELECT DISTINCT p.BusinessEntityID,p.FirstName,p.LastName, t.TotalDue
FROM Person.Person p,Sales.SalesPerson s,Sales.SalesOrderHeader t
WHERE p.BusinessEntityID = s.BusinessEntityID
and year(date_column) = '2008'

Related

Select SUM, Join two tables, group sum by OrderID in SQL Query

Currently trying to solve the reason for this error:
Column 'Orders.OrderID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
My goal is to group all the quantities for the items in each order ID, from the Order Details table
The SQL Server database I'm using is open to the public, as part of W3School's website tools. View it here if you'd like to test your query results: https://www.w3schools.com/sql/trysqlserver.asp?filename=trysql_func_sqlserver_datepart
I appreciate any help, and please let me know if you need more context/information to help me out. Thanks!
PS: please pardon my messy code, new to SQL :)
What I have so far:
SELECT
O.OrderID,
YEAR(O.OrderDate) AS OrderYear,
DATEPART(qq, O.OrderDate) AS OrderQuarter,
CONCAT(E.FirstName, SPACE(1), E.LastName) AS EmployeeName,
C.CustomerName,
S.ShipperName,
SUM(D.Quantity) AS OrderItems
FROM
((((Orders AS O
JOIN
Employees AS E ON O.EmployeeID = E.EmployeeID)
JOIN
Customers AS C ON O.CustomerID = C.CustomerID)
JOIN
Shippers AS S ON O.ShipperID = S.ShipperID)
JOIN
OrderDetails AS D ON O.OrderID = D.OrderID);
What I'm trying to achieve: my mentor gave me a small sample image to reference from. This is how I want to print out the quantities in my query with the column name OrderItems
If you remove the SUM function from SELECT, and remove the last join table statement, you'll see my query aggregates everything correctly up until OrderItems just fine. I have yet to add the OrderRevenue column and order it by descending Revenue value, but big brownie points if you want to go the extra mile and explain how to solve that as well.
Using the example data you provided through w3c:
SELECT o.OrderID, DATEPART(YEAR,o.OrderDate) AS OrderYear, DATEPART(QUARTER,o.OrderDate) AS OrderQuarter,
E.FirstName + ' ' + E.LastName AS EmployeeName, C.CustomerName, S.ShipperName, SUM(d.Quantity) AS Quantity--, SUM(d.Quantity*d.Price) AS OrderRevenue
FROM Orders o
INNER JOIN Employees e
ON o.EmployeeID = e.EmployeeID
INNER JOIN Customers c
ON o.CustomerID = c.CustomerID
INNER JOIN Shippers s
ON o.ShipperID = s.ShipperID
INNER JOIN OrderDetails d
ON o.OrderID = d.OrderID
GROUP BY o.OrderID, DATEPART(YEAR,o.OrderDate), DATEPART(QUARTER,o.OrderDate),
E.FirstName + ' ' + E.LastName, C.CustomerName, S.ShipperName
OrderID OrderYear OrderQuarter EmployeeName CustomerName ShipperName Quantity
--------------------------------------------------------------------------------------------------------
10249 1996 3 Michael Suyama Tradicao Hipermercados Speedy Express 49
10250 1996 3 Margaret Peacocl Hanari Carnes United Package 60
10368 1996 4 Andrew Fuller Ernst Handel United Package 78
10389 1996 4 Margaret Peacock Bottom-Dollar Marketse United Package 81
10418 1996 1 Margaret Peacock QUICK-Stop Speedy Express 146
10442 1997 1 Janet Leaverling Ernst Handel United Package 170
Your syntax error was because you did not define a GROUP BY and reference the columns which you wanted to aggregate to. When you use an aggregate function (like SUM or COUNT) you must also tell the engine which columns you will be grouping by.

How to get the Total Amount Each Customer Has Spent

I am making a database for a simple purchase, customer, employee, etc tables.
I am making a query that includes all of the employees who have boughten something, along with some of their data, and then the last field is supposed to have the total amount that they have boughten. However, I am not too sure on how to achieve this.
I am not quite sure on how to get the total to be almost like a sub-query to total up what the customer has gotten. For instance, the first 5 rows should have a total of 180.40.
I have been looking online for some help with totaling queries but couldn't find any good examples.
Any help would be wonderful! Thank you (I am pretty new to SQL and Access)!
Edit: Forgot to add this!
SELECT Employee.FirstName, Employee.LastName, Purchase.PurchaseID, Product.ProductName, Product.Price, Product.Price AS Total
FROM Employee
INNER JOIN (Customer INNER JOIN (Product INNER JOIN Purchase ON Product.ProductID = Purchase.ProductID)
ON Customer.CustomerID = Purchase.CustomerID) ON Employee.EmployeeID = Customer.EmployeeID;
Do you just want aggregation?
SELECT e.FirstName, e.LastName,
SUM(p.Price)
FROM ((Employee as e INNER JOIN
Customer as c
ON e.EmployeeID = c.EmployeeID
) INNER JOIN
Purchase pu
ON c.CustomerID = pu.CustomerID
) INNER JOIN
Product as p
ON p.ProductID = pu.ProductID
GROUP BY e.FirstName, e.LastName;

SQL Server query to select the highest quantity data row

I have been trying to find a similar case. I found a lot, but I still can't figure it out to adopt to my query.
I have a testDB in SQL Server that has 3 tables, as shown in picture below:
I created query as below:
SELECT P.FirstName,
P.LastName,
O.ProductType,
PO.ProductName,
PO.Quantity
FROM Persons AS P
INNER JOIN Orders AS O ON P.PersonID = O.PersonID
INNER JOIN ProductOrders AS PO ON PO.OrderID = O.OrderID;
Current result, it shows all records from ProductOrders. See picture below:
I want the result that only shows, for each Person name only record with the highest quantity. My expected result as shown in picture below:
Thanks very much for your help.
SQL Server has the TOP WITH TIES/ROW_NUMBER() trick that does this very elegantly:
SELECT TOP (1) WITH TIES P.FirstName, P.LastName, O.ProductType, PO.ProductName, PO.Quantity
FROM Persons P INNER JOIN
Orders O
ON P.PersonID = O.PersonID INNER JOIN
ProductOrders PO
ON PO.OrderID = O.OrderID
ORDER BY ROW_NUMBER() OVER (PARTITION BY P.PersonId, P.ProductType ORDER BY PO.Quantity DESC);
Use Window functions:
SELECT distinct P.FirstName
, P.LastName
, O.ProductType
, first_value(O.ProductName) OVER (Partition By P.FirstName, P.LastName, O.ProductType Order by PO.Quantity desc) as [Productname]
, max(PO.Quantity) OVER (Partition By P.FirstName, P.LastName, O.ProductType) as [Quantity]
FROM Persons AS P
INNER JOIN Orders AS O ON P.PersonID = O.PersonID
INNER JOIN ProductOrders AS PO ON PO.OrderID = O.OrderID;

AdventureWorks2012:Identify the sales persons who have sales less than $100,000 since beginning of 2008. Show: Sales person login ID

AdventureWorks2012: Identify the sales persons who have sales less than $100,000 since beginning of 2008.
Show: Sales person login ID.
I guess the tables will be
HumanResources.Employee
Sales.SalesPerson
Can someone plz help me. I have spent enough time
SELECT
E.LoginID
FROM
HumanResources.Employee AS E
JOIN
Sales.SalesPerson AS SP ON E.BusinessEntityID = SP.BusinessEntityID
WHERE
E.BusinessEntityID IN (SELECT BusinessEntityID
FROM Sales.SalesPerson
WHERE SalesQuota < 100000);
You're close - but you're not really looking at the sales that each sales person has had over the past years... The SalesQuota column that you're looking at in the SalesPerson table is usually a figure that is defined as a goal for the year - it's not an actual sum of all sales made.
I would try something like this:
-- determine the SUM of all sales, for all salespeople, since Jan 1, 2008
-- SUM the total of all sales (their TotalDue value) from the SalesOrderHeader table
;WITH SalesPerPerson AS
(
SELECT
sp.BusinessEntityID,
TotalSales = SUM(soh.TotalDue) -- SUM of all sales total amounts
FROM
Sales.SalesOrderHeader soh
INNER JOIN
Sales.SalesPerson sp ON soh.SalesPersonID = sp.BusinessEntityID
WHERE
soh.OrderDate >= '20080101' -- on all sales since Jan 1, 2008
GROUP BY
sp.BusinessEntityID
)
-- from that CTE, select the sales people who have had less than 100'000$ in
-- sales since Jan 1, 2008, and display those. Show LoginID and first and
-- last name (just for information purposes)
SELECT
p.FirstName, p.LAstName,
e.LoginID,
spp.*
FROM
SalesPerPerson spp
INNER JOIN
Person.Person p ON spp.BusinessEntityID = p.BusinessEntityID
INNER JOIN
HumanResources.Employee e ON p.BusinessEntityID = e.BusinessEntityID
WHERE
TotalSales < 100000.0
So if you really only need the LoginID, you can leave out the JOIN to the Person.Person table and remove the p.FirstName, p.LastName columns from the output.

SQL Query to find the maximum of a set of averages

This is a query based on the Northwind Database in MS SQL Server 2005.
First I have to get the average of the UnitPrice from OrderDetails table, and group it by ProductID for that particular column alone and alias it as AveragePrice.
Then I need to find the maximum(AveragePrice) which is nothing but the max of previous column, how can I do it??? This is a kind of very tricky for me its taking me ages to think on it.
select
O.CustomerID,
E.EmployeeID,
E.FirstName+space(1)+E.LastName FullName,
OD.OrderID,
OD.ProductID,
(select avg(DO.UnitPrice) from OrderDetails
DO where OD.ProductID = DO.ProductID
group by DO.ProductID) AveragePrice ,
from OrderDetails OD
join Orders O
on OD.OrderID = O.OrderID
join Customers C
on C.CustomerID = O.CustomerID
join Employees E
on E.EmployeeID = O.EmployeeID
This is not a Homework question, am learning SQL, but am really stuck at this point, please help me.
It's 2 steps: "the ungrouped maximum of the grouped averages"
You can expand this as needed which shows how to apply an aggregate on top of an aggregate
SELECT
MAX(AveragePrice) AS MaxAveragePrice
FROM
(
select
avg(UnitPrice) AS AveragePrice, ProductID
from
OrderDetails
group by
ProductID
) foo
Or with CTE
;WITH AvgStuff AS
(
select
avg(UnitPrice) AS AveragePrice
from
OrderDetails
group by
ProductID
)
SELECT
MAX(AveragePrice) AS MaxAveragePrice
FROM
AvgStuff