Add duplicate values in a table sql server - sql

Select
P.ProductName, WFS.Status, OI.Quantity, OI.Price
from
OrderItem As OI
Inner Join
Order As O On OI.OrderID = O.ID AND OI.ItemType = 1
Inner Join
Product P On OI.ProductID = P.ID
Inner Join
WorfFlowStatus As WFS On O.StatusID = WFS.ID
This query returns the rows:
ProductName Status Quantity Price
-------------------------------------------
ABC Shipped 10 100
ABC Shipped 10 100
BCE Pending 20 200
Now I want to select the same product in one row but quantity and price should be added. For e.g
ABC Shipped 20 200
BCE Pending 20 200
If status and productname is same than add the quantity and price and if product is not the same then no addition in quantity and price.

Select
P.ProductName,
WFS.Status,
sum(OI.Quantity),
sum(OI.Price)
from OrderItem As OI
Inner Join Order As O
On OI.OrderID = O.ID AND OI.ItemType = 1
Inner Join Product P
On OI.ProductID = P.ID
Inner Join WorfFlowStatus As WFS
On O.StatusID = WFS.ID
group by
P.ProductName,
WFS.Status

As pointed out by cha, the Group By clause is the key:
Select P.ProductName,WFS.Status,sum(OI.Quantity),sum(OI.Price)
from OrderItem As OI
Inner Join [Order] As O On OI.OrderID = O.ID AND OI.ItemType = 1
Inner Join Product P On OI.ProductID = P.ID
Inner Join WorkFlowStatus As WFS On O.StatusID = WFS.ID
group by productName, Status

'over with Partition by' can help.
For example
select ProductName,
Status,
Quantity,
(SUM(Quantity) OVER (PARTITION BY ProductName)) as TotalQuantity
FROM YourTableName and joins

select P.ProductName, WFS.Status, sum(OI.Quantity), sum(OI.Price)
from OrderItem OI, Order O, Product P, WorkFlowStatus WFS
where OI.OrderID = O.ID and OI.ItemType = 1 and
OI.ProductID = P.ID and
O.StatusID = WFS.ID
group by productName, Status

Related

Find Top 5 Customers for Beverages based on their total purchase value SQL

Here is the link to the Data Set.
https://www.w3schools.com/sql/trysql.asp?filename=trysql_asc
I have been trying to solve this but couldn't find a way to get the total purchase value while grouping with the customer table
I would recommend using a Common Table Expression (CTE) as, in my experience, it helps with scalability/maintenance down the road and easily enables you to see what the data is under the hood if you wanted to simply run the CTE itself.
I join the Customer to the Order to get the OrderID
I join the Order to OrderDetails to get the ProductID and Order Quantity
I join the OrderDetails to Products to get the Price
I join the Categories to filter for just Beverages
All this is wrapped as a CTE (similar to a subquery), on top of which I can now aggregate at the Customer level and sequence by Order Value in a descending fashion.
with beverage_orders_cte as(
SELECT c.CustomerName, o.OrderID
, od.OrderDetailID, od.ProductID, od.Quantity
, p.ProductName, p.Price
, od.Quantity * p.Price as OrderVal
,cat.CategoryName FROM Customers c
inner join Orders o
on c.CustomerID = o.CustomerID
inner join OrderDetails od
on o.OrderID = od.OrderID
inner join Products p
on od.ProductID = p.ProductID
inner join Categories cat
on p.CategoryID = cat.CategoryID and cat.CategoryID = 1
)
select CustomerName, SUM(OrderVal) as Revenue
From beverage_orders_cte
Group by CustomerName
Order by Revenue desc
Limit 5
Hope this helps, good luck.
Something like that?
SELECT c.customerid,
Sum(p.price)
FROM customers AS c
INNER JOIN orders AS o
ON o.customerid = c.customerid
INNER JOIN orderdetails AS od
ON od.orderid = o.orderid
INNER JOIN products AS p
ON p.productid = od.productid
GROUP BY c.customerid
ORDER BY Sum(p.price) DESC
LIMIT 5
Just following on from your quantity comment...
SELECT c.customerid,
Sum(p.price),
Sum(p.price * od.quantity)
FROM customers AS c
INNER JOIN orders AS o
ON o.customerid = c.customerid
INNER JOIN orderdetails AS od
ON od.orderid = o.orderid
INNER JOIN products AS p
ON p.productid = od.productid
GROUP BY c.customerid
ORDER BY Sum(p.price) DESC
LIMIT 5
I think this is the best optimized code.
Please try with this.
SELECT CustomerID, Count(Quantity * Price) AS Total
FROM Orders, OrderDetails, Products
Where Orders.OrderID = OrderDetails.OrderID AND Products.ProductID = OrderDetails.ProductID
Group by CustomerID
ORDER BY Total DESC
LIMIT 5

Gross sales of top ten customers that made at least 5 purchases of some Category in a specified year

I need to get (sales.customers) | year | gross_sales of top ten customers that made at least 5 purchases of Category "Beverages" in the year 2014. I have already written these SELECT queries, but since I am new to SQL, I think I am very inefficient in writing code. This does not work properly and there is probably a simpler way of doing it. I have also pinned a picture of an ER diagram .
SELECT
T6.COMPANYNAME, YEAR, GROSS_SALES
FROM
(SELECT T1.CUSTID
FROM
(SELECT R.CUSTID, COUNT(R.CUSTID) AS NUMBEROFSALES
FROM SALES.ORDERDETAILS O
RIGHT JOIN PRODUCTION.PRODUCTS P ON P.PRODUCTID = O.PRODUCTID
RIGHT JOIN SALES.ORDERS R ON R.ORDERID = O.ORDERID
INNER JOIN SALES.CUSTOMERS C1 ON R.CUSTID = C1.CUSTID
INNER JOIN PRODUCTION.CATEGORIES C2 ON P.CATEGORYID = C2.CATEGORYID
WHERE C2.CATEGORYNAME = 'Beverages' AND YEAR(R.ORDERDATE) = 2014
GROUP BY R.CUSTID
ORDER BY SUM(R.CUSTID) DESC) T1
--HAVING COUNT(R.CUSTID) > 5
RIGHT JOIN
(SELECT R.CUSTID, SUM(O.UNITPRICE) AS MONEYSPENT
FROM SALES.ORDERDETAILS O
RIGHT JOIN PRODUCTION.PRODUCTS P ON P.PRODUCTID = O.PRODUCTID
RIGHT JOIN SALES.ORDERS R ON R.ORDERID = O.ORDERID
INNER JOIN SALES.CUSTOMERS C1 ON R.CUSTID = C1.CUSTID
INNER JOIN PRODUCTION.CATEGORIES C2 ON P.CATEGORYID = C2.CATEGORYID
WHERE C2.CATEGORYNAME = 'Beverages' AND YEAR(R.ORDERDATE) = 2014
GROUP BY R.CUSTID
ORDER BY SUM(O.UNITPRICE) DESC) T2 ON T1.CUSTID = T2.CUSTID
ORDER BY T1.NUMBEROFSALES DESC
LIMIT 10) T5
INNER JOIN
(SELECT DISTINCT(T4.COMPANYNAME), T4.CUSTID, YEAR, GROSS_SALES
FROM
(SELECT R.CUSTID AS CUSTID, YEAR(R.ORDERDATE) AS YEAR, SUM(O.UNITPRICE * O.QTY * (1 - O.DISCOUNT)) AS GROSS_SALES
FROM SALES.ORDERDETAILS O
RIGHT JOIN SALES.ORDERS R ON R.ORDERID = O.ORDERID
INNER JOIN SALES.CUSTOMERS C1 ON R.CUSTID = C1.CUSTID
GROUP BY R.CUSTID, YEAR(R.ORDERDATE)
ORDER BY YEAR(R.ORDERDATE)) T3
INNER JOIN
(SELECT C.COMPANYNAME, C.CUSTID
FROM SALES.ORDERS R
INNER JOIN SALES.CUSTOMERS C ON R.CUSTID = C.CUSTID) T4 ON T3.CUSTID = T4.CUSTID) T6 ON T5.CUSTID = T6.CUSTID
I'm not going to try and fix your code or explain the misakes there, as there are many of them. Instead based on your requirements I wrote a query that solves the problem. I show it in steps below which should make clear the process I used to solve the problem.
First how do we find the top ten customers that made 5 purchases of Beverages?
Take customer table and join to orders with beverages (inner join will exclude customers that don't meet criteria)
SELECT CUSTOMERID
FROM CUSTOMERS C
JOIN ORDERS O ON C.CUSTOMERID = O.CUSTOMERID
JOIN ORDER_DETAILS OD ON O.ORDERID = OD.ORDERID
JOIN PRODUCTS P ON OD.PRODUCTID = P.PRODUCTID
JOIN CATEGORIES C ON P.CATEGORYID = C.CATEGORYID AND C. CATEGORY_NAME = 'Beverages'
WHERE YEAR(ORDER_DATE) = 2014
GROUP BY CUSTOMERID
HAVING COUNT(ORDER_DETAILS) >= 5
Now we need the sum of order (for 2014) by customers which looks like this:
SELECT CUSTOMERID, YEAR(ORDER_DATE) AS YEAR, SUM(OD.UNIT_PRICE*OD.QUANTITY) AS TOTAL_SPEND
FROM CUSTOMERS C
JOIN ORDERS O ON C.CUSTOMERID = O.CUSTOMERID
JOIN ORDER_DETAILS OD ON O.ORDERID = OD.ORDERID
WHERE YEAR(ORDER_DATE) = 2014
GROUP BY CUSTOMERID, YEAR(ORDER_DATE)
Now we just combine these two queries like this:
SELECT CUSTOMERID, YEAR(ORDER_DATE) AS YEAR, SUM(OD.UNIT_PRICE*OD.QUANTITY) AS TOTAL_SPEND
FROM CUSTOMERS C
JOIN ORDERS O ON C.CUSTOMERID = O.CUSTOMERID
JOIN ORDER_DETAILS OD ON O.ORDERID = OD.ORDERID
JOIN (
SELECT CUSTOMERID
FROM CUSTOMERS C
JOIN ORDERS O ON C.CUSTOMERID = O.CUSTOMERID
JOIN ORDER_DETAILS OD ON O.ORDERID = OD.ORDERID
JOIN PRODUCTS P ON OD.PRODUCTID = P.PRODUCTID
JOIN CATEGORIES C ON P.CATEGORYID = C.CATEGORYID AND C. CATEGORY_NAME = 'Beverages'
WHERE YEAR(ORDER_DATE) = 2014
GROUP BY CUSTOMERID
HAVING COUNT(ORDER_DETAILS) >= 5
) as SUB ON SUB.CUSTOMERID = C.CUSTOMERID
WHERE YEAR(ORDER_DATE) = 2014
GROUP BY CUSTOMERID, YEAR(ORDER_DATE)
ORDER BY SUM(OD.UNIT_PRICE*OD.QUANTITY)
LIMIT 10
Note I did not test this but just wrote the SQL since I don't have a db to test against so there might be typos
Also Note: I'm expect it is possible to remove the sub query as it is doing a lot of the same joins the outer query is-- but we want to make sure we get the correct result and it is easier to see it is correct this way. You can also test the sub-query by itself to make sure it returns expected results.

Save SQL Query Results in Variable

I have the following SQL Query, but it is very repetitive and so I am wondering if this can be cleaned up by storing the results of a SQL Query in a variable.
What I have is (which works, can be tested here)
SELECT ProductName FROM (
SELECT ProductName, SUM(Quantity) AS ProductQuantity FROM
(SELECT CustomerID FROM Customers AS C
WHERE Country = 'Germany') AS CG
INNER JOIN Orders AS O
ON CG.CustomerID = O.CustomerID
INNER JOIN OrderDetails AS OD
ON O.OrderID = OD.OrderID
INNER JOIN Products as P
ON OD.ProductID = P.ProductID
GROUP BY ProductName)
WHERE ProductQuantity = (
SELECT MAX(ProductQuantity) FROM (
SELECT ProductName, SUM(Quantity) AS ProductQuantity FROM
(SELECT CustomerID FROM Customers AS C
WHERE Country = 'Germany') AS CG
INNER JOIN Orders AS O
ON CG.CustomerID = O.CustomerID
INNER JOIN OrderDetails AS OD
ON O.OrderID = OD.OrderID
INNER JOIN Products as P
ON OD.ProductID = P.ProductID
GROUP BY ProductName))
And as you could tell the following code is repeated twice, is there any way I can do this without repeating this code:
(SELECT ProductName, SUM(Quantity) AS ProductQuantity FROM
(SELECT CustomerID FROM Customers AS C
WHERE Country = 'Germany') AS CG
INNER JOIN Orders AS O
ON CG.CustomerID = O.CustomerID
INNER JOIN OrderDetails AS OD
ON O.OrderID = OD.OrderID
INNER JOIN Products as P
ON OD.ProductID = P.ProductID
GROUP BY ProductName)
You can use CTE to avoid looping, maybe like this:
with cte as (
SELECT ProductName, SUM(Quantity) AS ProductQuantity FROM
(SELECT CustomerID FROM Customers AS C
WHERE Country = 'Germany') AS CG
INNER JOIN Orders AS O
ON CG.CustomerID = O.CustomerID
INNER JOIN OrderDetails AS OD
ON O.OrderID = OD.OrderID
INNER JOIN Products as P
ON OD.ProductID = P.ProductID
GROUP BY ProductName
)
SELECT ProductName
FROM cte
where ProductQuantity = (SELECT MAX(ProductQuantity) FROM cte)

How to Sum Total in Header Detail Tables

Please, I need your help, I'm new to the subject, so I have tow tables Order table and Order Detail table. I want to sum order amount in the order table and group by the product id exists in the order detail table. I'm getting repeated rows.
select p.productName
SUM(o.Amount - o.discount) as OrdersTotal
FROM dbo.order o
inner join
OrderDetail d
ON o.orderid = d.orderid
inner join
dbo.product p
ON d.productid = p.productid
where o.orderdate >= #fromdate
and o.orderdate <= #todate
group by p.productname, o.discount
the result I'm getting is as follow
product name orders total
------------ ------------
product A 150
product A 20
product B 45
product B 13
so please, how can I fix this result? Thanks
You should only group on the product name, so that all records with the same product name are included in the sum of the amount:
select p.productName
SUM(o.Amount) as OrdersTotal
FROM dbo.order o
inner join
OrderDetail d
ON o.orderid = d.orderid
inner join
dbo.product p
ON d.productid = p.productid
where o.orderdate >= #fromdate
and o.orderdate <= #todate
group by p.productname

How to multiply 2 columns and then SUM the results?

I'm learning SQL and I couldn't find the solution to my problem anywhere on he forums. Anyway, I'm using a www.dofactory.com SQL Sandbox and I've made a query:
select customer.LastName, Product.ProductName, OrderItem.Quantity, Product.UnitPrice, OrderItem.Quantity*Product.UnitPrice AS "Quantity x UnitPrice"
FROM Customer
JOIN [Order] ON [Order].CustomerID = Customer.ID
JOIN OrderItem ON OrderItem.OrderId = [Order].ID
JOIN Product ON Product.Id = OrderItem.ProductId
where
[Order].TotalAmount = (select max([Order].TotalAmount) FROM [Order])
And result:
LastNam ProductName Quantity UnitPrice Quantity x UnitPrice
Kloss Côte de Blaye 60 263.50 15810.00
Kloss Chartreuse verte 80 18.00 1440.00
Now I want to SUM the whole Column "Quantity x UnitPrice". What should I do?
You use SUM(). Something like this:
SELECT SUM(oi.Quantity * oi.UnitPrice) AS Summary
FROM Customer c JOIN
[Order] o
ON o.CustomerID = c.ID JOIN
OrderItem oi
ON oi.OrderId = o.ID JOIN
Product p
ON p.Id = oi.ProductId
WHERE o.TotalAmount = (select max(o2.TotalAmount) FROM [Order] o2);
Note the use of table aliases. They make the query easier to write and to read.
This is SQL Server (T-SQL). You can use SUM and GROUP BY like so. I've done it in a subquery, which is how I'd approach this sort of thing.
select LastName, ProductName, Quantity, UnitPrice, SUM(Summary)
from (
select customer.LastName, Product.ProductName, OrderItem.Quantity, Product.UnitPrice, OrderItem.Quantity*OrderItem.UnitPrice AS Summary, [Order].TotalAmount
FROM Customer
JOIN [Order] ON [Order].CustomerID = Customer.ID
JOIN OrderItem ON OrderItem.OrderId = [Order].ID
JOIN Product ON Product.Id = OrderItem.ProductId
where
[Order].TotalAmount = (select max([Order].TotalAmount) FROM [Order])) x
group by LastName, ProductName, Quantity, UnitPrice