SQL Sum two rows with the same ID - sql

I have two tables (orders and transfers) and I would like to sum up only the amount in casese where there are multiple transfers per order.
Thsi is my SQL. The sum works correctly, but SQL still returns two lines - I would just liek to see one line.
SQL:
Select
OrderId,
CustomerId,
SUM(Amount) over (partition by O.OrderId) AS Amount
FROM Orders O
LEFT JOIN Transfers T ON O.OrderId = T.OrderId
Orders:
OrderId
CustomerId
Order_1
Customer_1
Transfers:
TransferID
Amount
OrderId
Transfer_1
5
Order_1
Transfer_2
5
Order_1
This is my expected result:
OrderId
Customer_Id
Amount
Order_1
Customer_1
10
But what I get is:
OrderId
Customer_Id
Amount
Order_1
Customer_1
10
Order_1
Customer_1
10

You need a basic GROUP BY:
SELECT
o.OrderId,
o.CustomerId,
SUM(t.Amount) AS Amount
FROM Orders o
LEFT JOIN Transfers t ON o.OrderId = t.OrderId
GROUP BY
o.OrderId,
o.CustomerId;

Related

Count between multiple tables

I have these 3 tables with the following structures:
Products
product_id | category_id | product_name
Customers
customer_id | customer_name
Orders
order_id | customer_id | product_id
I need to write a SQL query that will print the top customers regarding the number of categories they have bought products from (the best customer is the one that has bought from the most categories).
Can anyone show me how to do that?
I tried like this, but I get the following error "not a GROUP BY expression":
select
(select customer_name
from customers
where customers.customer_id = orders.customer_id) as name,
(select count(category_id)
from products
where products.product_id = orders.product_id)
from
orders
group by
customer_id
order by
count(customer_id) desc;
I managed to make the top regarding how many products the customers bought. The solution I used is:
select
(select customer_name from customers
where customers.customer_id = orders.customer_id) as name,
count(product_id) as "number of ordered products"
from
orders
group by
customer_id
order by
count(product_id) desc;
Nested queries for this? Sheesh...
Just join them already.
And then order by the unique categories
SELECT c.customer_name
, COUNT(DISTINCT p.category_id) AS TotalOrderedCategories
FROM Orders o
LEFT JOIN Customers c ON c.customer_id = o.customer_id
LEFT JOIN Products p ON p.product_id = o.product_id
GROUP BY c.customer_name
ORDER BY COUNT(DISTINCT p.category_id) DESC
Then depending on your RDBMS flavor, add a TOP or a LIMIT.

select different data from several tables

How could I select
| Customer_name | Num_of_AllTime_Orders | Num_of_different_Products_That_Customer_Ordered |
as a table when each data is from a different table?
I tried to count customers, join tables and group by... but no luck.
SELECT CompanyName, count(Customer_ID) from dbo.CUSTOMERS join dbo.ORDERS on CUSTOMERS.Customer_ID=ORDERS.CustomerID
Customers_Table:
CustomerID | Customer_Name
Orders_Table:
OrderID| Customer_ID
Order_Detail_Table:
OrderID| Product_ID |
I expect the output of a table which has these columns :
1. Customer_Name
2. Num_of_AllTime_Orders - how many orders that costumer made?
3. Num_of_different_Products_That_Customer_Ordered - how many different products that customer ordered?
Select CUSTOMERS.Customer_Name
,count(distinct ORDERS.OrderID) as Num_of_AllTime_Orders
,count(distinct Order_Detail_Table.Product_ID) as Num_of_different_Products_That_Customer_Ordered
from dbo.CUSTOMERS
join dbo.ORDERS on CUSTOMERS.CustomerID = ORDERS.Customer_ID
join dbo.Order_Detail_Table on ORDERS.OrderID = Order_Detail_Table.OrderID
group by CUSTOMERS.Customer_Name
SELECT Company_Name = C.CompanyName, NumOfOrders = COUNT (DISTINCT O.OrderID), NumOfProducts = COUNT (DISTINCT OD.ProductID)
FROM dbo.CUSTOMERS AS C JOIN ORDERS AS O ON C.Customer_ID=O.CustomerID JOIN ORDERDETAILS AS OD ON OD.OrderID=O.OrderID
GROUP BY C.CompanyName
ORDER BY 1

Having an issue with the last part of my Oracle SQL query

I'm having trouble with a problem (and yes it is homework).. The question is:
Write a SELECT statement that returns one row for each customer that has orders with these columns:
The email_address from the Customers table
A count of the number of orders
The total amount for each order (Hint: First, subtract the discount amount from the price. Then, multiply by the quantity.)
Return only those rows where the customer has more than 1 order.
Sort the result set in descending sequence by the sum of the line item amounts.
My query for this part works. It is:
SELECT email_address, COUNT(o.order_id) as number_of_orders, sum((item_price-discount_amount)*quantity) As Total
FROM Customers c JOIN Orders o
ON c.customer_id = o.customer_id
JOIN order_items oi on oi.order_id =o.order_id
GROUP BY email_address
HAVING COUNT (o.order_id) > 1
ORDER BY number_of_orders DESC;`
After that, I'm supposed to modify that query so that it only counts and totals line items that have an item_price value greater than 400. I can't seem to figure it out. Can someone please point me in the right direction?
BTW, it's the My Guitar Shop database.
You will have to add a filter for item_price greater than 400 assuming item_price is part of order_items table.
SELECT email_address, COUNT(o.order_id) as number_of_orders, sum((item_price-discount_amount)*quantity) As Total
FROM Customers c JOIN Orders o
ON c.customer_id = o.customer_id
JOIN order_items oi on oi.order_id =o.order_id
where oi.item_price > 400
GROUP BY email_address
HAVING COUNT (o.order_id) > 1
ORDER BY number_of_orders DESC;
SELECT email_address, COUNT(o.order_id) as number_of_orders, sum((item_price-discount_amount)*quantity) As Total
FROM Customers c JOIN Orders o
ON c.customer_id = o.customer_id
JOIN (
SELECT order_id,
CASE WHEN item_price < 400 THEN 0 ELSE item_price END,
--other columns you need
FROM order_items ) oi on oi.order_id =o.order_id
GROUP BY email_address
HAVING COUNT (o.order_id) > 1
ORDER BY number_of_orders DESC;
This is should work.
Also, you should always use table aliases when addressing a coulmn- even if there are no name clashed. It improves readability and prevent you from making nasty mistakes.

Compare a table with a count result from another table and add the names that have a zero count

I am counting how many times a company has ordered. Then I am only showing if a company has ordered less than 5 times. I am then checking it against the table with all company names to see what company has not ordered, which would not show up on the order table, then add their name on the displayed list.
What I have tried:
Select Orders.CustomerID, Count(Orders.CustomerID) AS OrderCount
From Orders Left Join Customers
On Orders.CustomerID = Customers.CustomerID
Group By Orders.CustomerID
Having Count(Orders.CustomerID) <5
This is totally wrong:
Select CustomerID
From Customers
Where EXISTS
(Select CustomerID, Count(CustomerID) AS 'OrderCount'
From Orders
Group BY CustomerID
Having Count(Orders.CustomerID) < 5)
I need to somehow compare the list of names before I ask it to see which ones have ordered less than 5 times.
Thanks
If you want to use LEFT JOIN, interchange the table names since you want to show values from Customers, otherwise use RIGHT JOIN instead.
SELECT Customers.CustomerID,
COUNT(Orders.CustomerID) AS OrderCount
FROM Customers
LEFT JOIN Orders
ON Orders.CustomerID = Customers.CustomerID
GROUP BY Customers.CustomerID
HAVING COUNT(Orders.CustomerID) < 5
using EXISTS()
SELECT CustomerID
FROM Customers c
WHERE EXISTS
(
SELECT 1
FROM Orders o
WHERE o.CustomerID = c.CustomerID
GROUP BY CustomerID
HAVING COUNT(CustomerID) < 5
)
Try this:
SELECT C.CustomerID, C.CustomerName, COUNT(O.CustomerID) AS OrderCount
FROM Customers C
LEFT JOIN Orders O ON O.CustomerID = C.CustomerID
GROUP BY C.CustomerID
HAVING OrderCount < 5
ORDER BY OrderCount, C.CustomerName

Calculating the SUM of (Quantity*Price) from 2 different tables

I have two tables as follows
PRODUCT table
Id | Name | Price
And an ORDERITEM table
Id | OrderId | ProductId | Quantity
What I'm trying to do is, calculate the subtotal price for each product (Quantity*Price) then SUM the TOTAL value for the entire order..
I'm trying something like this
SELECT Id, SUM(Quantity * (select Price from Product where Id = Id)) as qty
FROM OrderItem o
WHERE OrderId = #OrderId
But of course that doesn't work :)
Any help appreciated!
EDIT: I only want to show the grand total for the entire order, so basically the sum of Quantity*Price for every row in OrderItem. Here's some sample data.
Sample Data
TABLE Product
Id Name Price
1 Tomatoes 20.09
4 Cucumbers 27.72
5 Oranges 21.13
6 Lemons 20.05
7 Apples 12.05
Table OrderItem
Id OrderId ProductId Quantity
151 883 1 22
152 883 4 11
153 883 5 8
154 883 6 62
M
Use:
SELECT oi.orderid,
SUM(oi.quantity * p.price) AS grand_total,
FROM ORDERITEM oi
JOIN PRODUCT p ON p.id = oi.productid
WHERE oi.orderid = #OrderId
GROUP BY oi.orderid
Mind that if either oi.quantity or p.price is null, the SUM will return NULL.
i think this - including null value = 0
SELECT oi.id,
SUM(nvl(oi.quantity,0) * nvl(p.price,0)) AS total_qty
FROM ORDERITEM oi
JOIN PRODUCT p ON p.id = oi.productid
WHERE oi.orderid = #OrderId
GROUP BY oi.id
I think this is along the lines of what you're looking for. It appears that you want to see the orderid, the subtotal for each item in the order and the total amount for the order.
select o1.orderID, o1.subtotal, sum(o2.UnitPrice * o2.Quantity) as order_total from
(
select o.orderID, o.price * o.qty as subtotal
from product p inner join orderitem o on p.ProductID= o.productID
where o.orderID = #OrderId
)as o1
inner join orderitem o2 on o1.OrderID = o2.OrderID
group by o1.orderID, o1.subtotal
select orderID, sum(subtotal) as order_total from
(
select orderID, productID, price, qty, price * qty as subtotal
from product p inner join orderitem o on p.id = o.productID
where o.orderID = #orderID
) t
group by orderID
I had the same problem as Marko and come across a solution like this:
/*Create a Table*/
CREATE TABLE tableGrandTotal
(
columnGrandtotal int
)
/*Create a Stored Procedure*/
CREATE PROCEDURE GetGrandTotal
AS
/*Delete the 'tableGrandTotal' table for another usage of the stored procedure*/
DROP TABLE tableGrandTotal
/*Create a new Table which will include just one column*/
CREATE TABLE tableGrandTotal
(
columnGrandtotal int
)
/*Insert the query which returns subtotal for each orderitem row into tableGrandTotal*/
INSERT INTO tableGrandTotal
SELECT oi.Quantity * p.Price AS columnGrandTotal
FROM OrderItem oi
JOIN Product p ON oi.Id = p.Id
/*And return the sum of columnGrandTotal from the newly created table*/
SELECT SUM(columnGrandTotal) as [Grand Total]
FROM tableGrandTotal
And just simply use the GetGrandTotal Stored Procedure to retrieve the Grand Total :)
EXEC GetGrandTotal