Sorting results of aggregate function - sql

This code:
SELECT ProductID, COUNT(ProductID) AS Occurrences
FROM OrderDetails
Group By ProductID;
is my attempt to take the productIDs that occur in an orderDetails table, count how many orders contain that product, and then sort the productID counts descending. In layman's terms, I want to show which products are the most popular, by showing their count in descending order so that the products that "sold" the most will occur at the top. The issue I have is that when I tried to use "Group by" with "Occurrences", it spat out an error that I cannot use aggregate functions with group by. If I group by ProductID, it shows the counts all over the place, which isn't the most useful way to present the information.

This should work:
SELECT ProductID, COUNT(ProductID) AS Occurrences
FROM OrderDetails
Group By ProductID
Order By COUNT(ProductID) DESC;

What you really want to use if you want to know the popularity of the products is SUM not COUNT:
SELECT ProductID,
sum(Qty) AS Occurrences
FROM OrderDetails
Group By ProductID
Order By sum(Qty) DESC;
COUNT will give you interesting results. Or you could use count of orders like this:
select ProductID
count(distinct OrderNumber) as NumberOfOrders
from OrderDetails
group by ProductID
order by count(distinct OrderNumber) desc;

Related

List orderId, Number of Order Items, and Total Order Price - not a GROUP BY expression

I know the "not a GROUP BY expression" has been asked, but mine seems to be very different.
I'm trying to get a list of data from a view but I am getting the "not a GROUP BY expression" error.
Code:
Select orderid, count(orderid) as Number_Of_Order_Items , count(orderid) * orderprice as Total_Order_Price
from orderdetail
Group by orderid
order by orderid
Basically I am expecting to get the orderID, how many times that order ID appears and then multiply the number of times the orderID exists by the OrderPrice.
I have all of the non-aggregate clauses in my Group By, so what is happening here?
Just use sum() on the price:
Select orderid, count(orderid) as Number_Of_Order_Items,
sum(orderprice) as Total_Order_Price
from orderdetail
Group by orderid
order by orderid;
Note: This assume that orderprice is really a separate price on each detail record that needs to be summed up. In some cases, there might be a quantity column as well -- but then I would expect the column to be called something like productprice or unitprice.

how to match a value with SQL max(count) function?

I have a orderLine table looks like this
I would like to know which pizza is the best seller, and the quantity of pizza sold.
I've tried query:
select sum(quantity), pizza_name from order_line group by pizza_name;
it returns
which is almost what I want, But when I start adding Max function, it could not match the pizza name with the total quantity of pizza sold
For example:
select MAX(sum(quantity)), pizza_name from order_line group by pizza_name;
it returns following error:
"not a single-group group function"
I guess I could achieve this by using a sub-query, but I have no idea how to do this.
You don't need max for this. If you only want one pizza, then you can use order by and fetch first 1 row only (or something similar such as limit or top):
select sum(quantity), pizza_name
from order_line
group by pizza_name
order by sum(quantity)
fetch first 1 row only;
Or, if you want all such pizzas, use rank():
select p.*
from (select sum(quantity) as quantity, pizza_name,
rank() over (order by sum(quantity) desc) as seqnum
from order_line
group by pizza_name
) p
where seqnum = 1;
Both of the queries give the same desired result
SELECT PIZZA_NAME,
SUM(QUANTITY) "Total Quant"
FROM Order_line
GROUP BY PIZZA_NAME
ORDER BY "Total Quant" DESC
FETCH FIRST 1 row only;
SELECT PIZZA_NAME, "Total Quantity" FROM (
SELECT PIZZA_NAME,SUM(QUANTITY) "Total Quantity", RANK() OVER (ORDER BY SUM(QUANTITY) DESC) T FROM Order_line GROUP BY PIZZA_NAME
) query1 where query1.T=1 ;
You group by pizza_name to get sum(quantity) per pizza_name.
Then you aggregate again by using MAX on the quantity sum, but you don't specify which of the three pizza names to have in the result. You need an aggregate function on pizza_name as well, which you don't have. Hence the error.
If you want to use your query, you must apply the appropriate aggregation function on pizza_name, which is KEEP DENSE_RANK FIRST/LAST.
select
max(sum(quantity)),
max(pizza_name) keep (dense_rank last order by sum(quantity))
from order_line
group by pizza_name;
But on one hand Gordon's queries are more readable in my opinion. And on the other this double aggregation is Oracle specific and not SQL standard. Unexperienced readers may be confused that the query produces one result row in spite of the GROUP BY clause.

SQL Using sum command with "in" clause

I have sql tables listed as picture below.
And my Query is :
Select * from tblOrderDetails where OrderID in
(Select OrderID from tblOrders where CustomerID = 523456)
Which returns values from tblOrderDetails like
Query brings all sale details for selected customer as expceted. But I want to use SUM on rows which has same ProductID. Expected output should look like this :
Rows with same productID, quantity and price gets summed and also rows are merged. But it must be done within selected CustomerID.
I've tried SUM command with many different ways but can't get it to work. Please suggest. Thanks.
It sounds like you don't know about the GROUP BY clause.
Perhaps this is what you are trying to do?
Select CustomerID,ProductId,SUM(Quantity) Quantity,SUM(TotalPrice) TotalPrice from tblOrderDetails where OrderID in (Select OrderID from tblOrders where CustomerID = 523456)
GROUP BY CustomerID,ProductId
This groups everything by same customer then by same products, allowing the SUMs only on those merged subsets
You'll be wanting to use SUM and GROUP BY to attain the results you're looking for.
SELECT ProductID, SUM(Quantity) AS Quantity, SUM(TotalPrice) AS TotalPrice
FROM tblOrderDetails
WHERE OrderID IN
(
SELECT OrderID
FROM tblOrders
WHERE CustomerID = 523456
)
GROUP BY ProductID

Counting records in a table given corresponding ID

This seems like such an easy query to run yet I cannot get it to work and I'm starting to rethink why I chose to tackle this project.
I am trying to find how many records are in a table where an id is identical. For example
select productid, productgroup, shelflvl, shelfaisle, Count(Shelfaisle) AS totalaisles
from productlocation
Where productid= productid AND productgroup = 'canned'
Group By productid, productgroup, shelflvl, shelfaisle
A product with the same id can be in a different aisle and on a different shelflvl. All I am trying to do is see how many aisles a product is in and I cannot for the life of me get it to work properly.
Any help is appreciated thank you!
I'm assuming a product cannot belong to many productgroups.
Remove Shelfaisle from GROUP BY as this is what you're trying to count.
Also, a COUNT(DISTINCT Shelfaisle) would prevent duplicates (if applicable).
Lastly, you don't need a productid=productid condition which apparently always yields true.
Cut a long story short:
select
productid, productgroup, shelflvl, Count(distinct Shelfaisle) AS totalaisles
from productlocation
Where productgroup = 'canned'
Group By productid, productgroup, shelflvl
Don't group by the column you are trying to aggregate:
select productid, productgroup, Count(Shelfaisle) AS totalaisles
from productlocation
Where productid=productid AND productgroup = 'canned'
Group By productid, productgroup
How about:
select productid, productgroup, Count(shelfaisle) AS totalaisles
from productlocation
Where productid= productid AND productgroup = 'canned'
Group By productid,productgroup
You are adding in additional columns to group by, which means that you can't isolate the product as the thing to count. You are counting products on specific rows on specific shelflevels, when you only need the product and shelfaisle.
This would work:
SELECT productid, shelflvl, MIN(productgroup) AS productgroup,
COUNT(Shelfaisle) AS totalaisles
FROM productlocation
WHERE productgroup = 'canned'
GROUP BY productid, shelflvl
ORDER BY productid;

SQL, DISTINCT product_id, orderQuantity

Here is the given question:
Show me a list of the product codes along with the number of times that each code has been ordered (note, order quantity does affect the number of total times ordered); only include product codes that have been ordered at least once?
I have tried the following
SELECT DISTINCT productId, orderQuantity
FROM Order
WHERE (orderQuantity > 0);
The table comes up with duplicate product ids. How do I get a table of distinct product ids with the SUM of their order quantities?
I think this is what you're looking for:
SELECT productID, SUM(orderQuantity)
FROM Order
WHERE orderQuantity > 0
GROUP BY productID
You have to use an aggregate function, in this case SUM(), to have the sum of your quantities and you want the sums to be grouped by each product, in your case productID.
To understand how this works, just try removing the GROUP BY statement and the productID from the SELECT statement and the query will return the SUM of all quantities.
SELECT SUM(orderQuantity)
FROM Order
WHERE orderQuantity > 0
Then, if you add just the GROUP BY productID you will get the sum of quantities ordered for each product.
SELECT SUM(orderQuantity)
FROM Order
WHERE orderQuantity > 0
GROUP BY productID
Then just add the productID back in the SELECT statement to understand the information displayed.