How do you add OrderID to this? I cant get it to display without getting a error on all OrderID sections - sql

I cant get it to display without getting an error on all OrderID sections. I tried adding it to the top and then the subquery and it errors saying ambouious column. How would be the correct way to do this?
TABLE SETUP:
Customers Table:
CustomerID, EmailAddress, Password, FirstName, LastName, ShippingAddressID, BillingAddressID
OrderItems Table:
ItemID, OrderID, ProductID, ItemPrice, DiscountAmount, DiscountTotal, PriceTotal, ItemTotal, Quantity
Order Table:
OrderID, CustomerID, OrderDate, ShipAmount, TaxAmount, ShipDate, ShipAddressID, CardType, CardNumber,CardExpires, BillingAddressID
CODE:
SELECT c.EmailAddress, MAX(OrderCost) AS
LargestOrder
FROM Customers c
JOIN ORDERS o ON c.CustomerID = o.CustomerID
JOIN (Select Orders.OrderID, ItemPrice * Quanity AS OrderCost FROM Orders, OrderItems
WHERE OrderItems.OrderID = Orders.OrderID)Largest
ON Largest.OrderID = o.OrderID
GROUP BY c.EmailAddresses

It really helps for you to put some effort into a script that demonstrates your problem. That way no one needs to guess about how you defined things and the actual values you use.
Here is one approach based on my guess. Note "one" - there are techniques to achieve the same result. The cte calculates the total cost for each order just like your code attempted. Since you suggested top, I used that as well to demonstrate its usage. Grabbing the top first row based on descending OrderCost will get you the order with the highest total cost. Just join the cte to Orders and Customers to include the columns you desire.
with cte as (select OrderID, sum(ItemPrice * Quantity) as OrderCost
from #OrderItems
group by OrderID)
select top 1 Ord.OrderID, Ord.OrderDate, cust.EmailAddress, cte.OrderCost
from cte inner join #Orders as Ord
on cte.OrderID = Ord.OrderID
inner join #Customers as Cust
on Ord.CustomerID = Cust.CustomerID
order by cte.OrderCost desc;
rextester here
And everyone hopes that you are not actually saving credit card information - because that would be bad in many ways.

Related

Find customer who bought least on W3schools SQL

I'm new to SQL Server and I'm trying to do some exercises. I want to find customers who bought least on W3schools database. My solution for this case is:
Join Customers with OrderDetails via CustomerID
Select CustomerNames that have least OrderID appeared after using JOIN.
Here is my query:
SELECT COUNT(OrderID), CustomerID
FROM Orders
GROUP BY CustomerID
ORDER BY COUNT(CustomerID) ASC
HAVING COUNT(OrderID) = '1'
When I ran this query, message says "Syntax error near "Having". What happened with my query?
Please help me to figure out.
My solution for this case is:
Join Customers with OrderDetails via CustomerID
Select CustomerNames that have least OrderID appeared after using JOIN.
As #thorsten-kettner lamented:
You say in your explanation that you join and then show the customer
name. Your query does neither of the two things...
Furthermore, your question has severe grammatical errors making it hard to decipher.
I want to find customers who bought least on W3schools database.
Nonetheless,
The Try-SQL Editor at w3schools.com
To get the list of customers who have at least 1 order:
SELECT C.CustomerName FROM [Customers] AS C
JOIN [Orders] AS O
ON C.CustomerID = O.CustomerID
GROUP BY C.CustomerID
ORDER BY C.CustomerName
To get the list of customers who have exactly 1 order:
SELECT C.CustomerName FROM [Customers] AS C
JOIN [Orders] AS O
ON C.CustomerID = O.CustomerID
GROUP BY C.CustomerID
HAVING COUNT(O.OrderID) = 1
ORDER BY C.CustomerName
To get the customer who made the least number of orders:
Including the ones who made no order. Use JOIN instead of LEFT JOIN if you only want to consider the ones who made at least one order.
You can remove LIMIT 1 to get the whole list sorted by the number of orders placed.
SELECT C.CustomerName, COUNT(O.OrderID) FROM [Customers] AS C
LEFT JOIN [Orders] AS O
ON C.CustomerID = O.CustomerID
GROUP BY C.CustomerID
ORDER BY COUNT(O.OrderID), C.CustomerName
LIMIT 1;
Addendum
As commented by #sticky-bit ,
The ORDER BY clause has to come after the HAVING clause.
You want a TOP 1 WITH TIES query, something like this:
SELECT TOP 1 WITH TIES CustomerID
FROM Orders
GROUP BY CustomerID
ORDER BY COUNT(OrderID);
In case you are using MySQL, try the following version:
SELECT CustomerID
FROM Orders
GROUP BY CustomerID
HAVING COUNT(OrderID) = (
SELECT COUNT(OrderID)
FROM ORDERS
GROUP BY CustomerID
ORDER BY COUNT(OrderID)
LIMIT 1
);

How to write this SQL query more elegantly ( joining + max query )

Ok I am using the following example from w3school
https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_all
and I want to get the date in which the amount was ordered
SELECT OrderDate
FROM Orders
WHERE OrderID = (SELECT OrderID
FROM OrderDetails
WHERE Quantity = (SELECT MAX(Quantity)
FROM OrderDetails));
This works but my guts tell me I need to use joining or having ??
You want the date of the order that has the maximum quantity.
It does not look like you do need two levels of subqueries. You could use a row-limiting subquery instead:
select orderdate
from orders
where orderid = (select orderid from from orderdetails order by quantity desc limit 1)
This is shorter, and does not fail if there is more than one order with the same, maximum quantity (while your original code does, because the subquery returns more than one row).
Another approach uses window functions:
select o.orderdate
from orders o
inner join (
select od.*, rank() over(order by quantity desc) rn
from orderdetails od
) od on od.orderid = o.orderid
where od.rn = 1
This will properly handle top ties, in the sense that it will return them all (while the first query returns only one of them).
I think this is much cleaner solution!
best regards
select max(od.quantity) as MaxOrder,orderdate
from orderdetails as od inner join orders as o on od.orderid=o.orderid

Left Join and Sum Each Individual Row

I have a table named orders (orderID, customerID, purchaseDate, and paymentType) and orderLine (orderID, upc, productName, quantity, price). I'm trying to join these two tables so that it primarily shows the orders table but then has a total price column for each order on the far right. This is what I have so far but it's adding the total for every single row into one. I want each individual row to have their own sum by multiplying quantity*price based on the orderID.
SELECT orders.orderID, SUM(orderLine.price * orderLine.quantity)
FROM orderLine
LEFT JOIN orders
ON orders.orderID = orderLine.orderID
You need to add group by clause
SELECT orders.orderID, SUM(orderLine.price * orderLine.quantity)
FROM orderLine
LEFT JOIN orders
ON orders.orderID = orderLine.orderID
grou by orders.orderID
SELECT orders.orderID, (SUM(orderLine.price * orderLine.quantity) Over (Order
By orders.orderID))
FROM orderLine
LEFT JOIN orders
ON orders.orderID = orderLine.orderID
Group By orders.orderID
You want all orders, so start with orders. Table aliases also make the query easier to write and to read:
SELECT o.orderID, SUM(ol.price * ol.quantity)
FROM orders o LEFT JOIN
orderLine ol
ON o.orderID = ol.orderID
GROUP BY o.orderID;
Then the answer to your question is GROUP BY.
You would have a very poor data model if you have orderlines that don't have a corresponding order, which is what your version of the query suggests.

SQL Server 2012 Query Confusion

I am a beginner with SQL and I cannot seem to come up with a correct query for this question:
Use a correlated subquery to return one row per customer, representing the customer’s oldest order (the one with the earliest date). Each row should include these three columns: EmailAddress, OrderID, and OrderDate.
I started by joining orders and customers table. EmailAddress is the only column needed from customers table.
SELECT EmailAddress, OrderDate, orderID
FROM Customers c JOIN orders o
ON c.CustomerID = o.CustomerID
A less complicated answer:
SELECT EmailAddress, OrderID, OrderDate AS OldestOrder
FROM Customers AS C
JOIN Orders AS O1
ON C.CustomerID = O1.CustomerID
WHERE O1.OrderDate =
(SELECT MIN(OrderDate)
FROM Orders AS O2
WHERE C.CustomerID = O2.CustomerID)
Use ROW_NUMBER() to get unique ids for each customer which orders by OrderDate in descending order. And the latest date will be RNO=1. Now do the filtration in outer query.
SELECT EmailAddress, OrderDate, orderID
FROM
(
SELECT ROW_NUMBER() OVER(PARTITION BY c.CustomerID ORDER BY OrderDate DESC)RNO,
EmailAddress, OrderDate, orderID
FROM Customers c JOIN orders o
ON c.CustomerID = o.CustomerID
)TAB
WHERE RNO=1
You can still use HAVING Clause and the IN Operator to achieve same results for this particular problem
Code:
SELECT DISTINCT EmailAddress, OrderID, OrderDate
FROM Customers
JOIN orders
ON Customers.CustomerID = Orders.CustomerID
GROUP BY EmailAddress, OrderID, OrderDate
HAVING OrderID IN (1,2,4,5,6,7,8)
ORDER BY EmailAddress ASC;

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