Query returning incorrect result - sql

I wrote the below SQL query for pulling the revenue of a specific product Id (500) but it's returning 9335 results but all same (duplicates).
DECLARE #ProductID char(3) = '500'
SELECT
P.ProductID,
P.Name,
P.Price,
S.Quantity,
CAST(Price * Quantity AS float) AS Revenue
FROM
Sales S
INNER JOIN
Products P ON S.ProductID = P.ProductID
WHERE
p.ProductID = #ProductID;

Presumably, you want aggregation:
SELECT P.ProductID, P.Name, P.Price,
SUM(Price*Quantity) as Revenue
FROM Sales S INNER JOIN
Products P
ON S.ProductID = P.ProductID
WHERE p.ProductID = #ProductID
GROUP BY P.ProductID, P.Name, P.Price;

Related

SQL Query to get highest values based on one column by grouping on another column

I am running the following SQL query to select the highest priced product in each product category in https://www.w3schools.com/sql/trysql.asp
SELECT p.ProductID, p.productName, p.Price, p.CategoryID, c.CategoryName
FROM [Categories] c
LEFT JOIN [Products] p
ON (c.CategoryID = p.CategoryID)
WHERE Price IN (SELECT Max(Price) FROM Products GROUP BY CategoryID)
ORDER BY p.CategoryID
However, the output that is generated is giving 2 results for some categories like category 3 and 4. Why is that happening? and how can I modify the code to get only highest result for each? Also, how do I get lowest for each category?
use row_number()
slect a.* from (SELECT p.ProductID, p.productName, p.Price, p.CategoryID, c.CategoryName,
row_number()over(partition by p.CategoryID order by p.Price desc) rn
FROM [Categories] c
LEFT JOIN [Products] p
ON c.CategoryID = p.CategoryID
) a where a.rn=1
APPLY comes to mind as perhaps the simplest approach:
SELECT p.ProductID, p.productName, p.Price, p.CategoryID, c.CategoryName
FROM categories c OUTER APPLY
(SELECT TOP (1) p.*
FROM Products p
WHERE p.CategoryID = c.CategoryID
ORDER BY p.Price DESC
) p
ORDER BY c.CategoryID

Hi i have some problems with a T-SQL using *

Group the ProductID orders, get a total by ProductID, the total of the orders and what represents the ProductID orders of the total order (that is a percentage). Columns Required: PercenofTotal (UnitPrice * Quantity), TotalAmount (UnitPrice * Quantity), PercentofTheTotal (UnitPrice * Quantity)
So this is my code, what i dont know is to do the percentofTheTotal and TotalAmount
SELECT P.ProductID, (P.UnitPrice * ODQuantity) AS tOTALaMOUNTByProductID, (P.UnitPrice * Quantity) as TotalAmount , (P.UnitPrice * OD.Quantity) as PercenofTotal
From Products as P,
From OrderDetails as OD
Group by P.ProductID
you're trying to do something complicated with simple statements that are not correct. Something like this could possibly do what you want to achieve.
USE AdventureWorks2014
GO
SELECT P.ProductID
, SUM(P.StandardCost * OD.OrderQty) AS TotalAmountByProductID
, MAX(SumTA.TotalAmount) AS TotalAmount
, (SUM(P.StandardCost * OD.OrderQty) / (MAX(SumTA.TotalAmount))*100) AS PercentOfTotal
FROM Production.Product as P
INNER JOIN Sales.SalesOrderDetail as OD on P.ProductID = OD.ProductID
LEFT OUTER JOIN (
SELECT max(pid) as pid, SUM(TA.TotalAmount) as TotalAmount
FROM
( SELECT '1' as pid, P.ProductID, SUM(P.StandardCost * OD.OrderQty) AS TotalAmount
FROM Production.Product as P
JOIN Sales.SalesOrderDetail as OD on P.ProductID = OD.ProductID
Group by P.ProductID
)AS TA
) AS SumTA ON SumTA.pid = '1'
Group by P.ProductID
ORDER BY PercentOfTotal Desc

Stuck doing a common table expression to calculate total orders for each product category using NORTHWND

Guys so as part of my job as a Data Support Analyst I am training up to become a software developer, my mentor gave me a group of test statements and this one seems way more advanced than anything I have done previously. The question is...
*
6) Write a subquery or common table expression to calculate total
orders for each product category. that will Write a query that will
bring back each product name, the total number of orders made for the
product and join to the subquery or CTE to calculate the percentage
of sales that product represents of its product category. For example,
if Category of Soaps has 2 products; Blue Soup and Red Soap, blue soup
had 40 orders and red soaps had 10 orders I would expect to see the
following rows: Product Name Total Orders % of Category Red
Soap 40 80%
Blue Soap 10 20%
*
So far I have managed to get the following but I'm struggling to progress past this...
;WITH [Products] (CategoryId, TotalNumberOfOrders)
AS (
SELECT p.CategoryId,
COUNT (OD.OrderID) as TotalNumberOfOrders
FROM [dbo].[Products] p
INNER JOIN [dbo].[Order Details] OD
ON p.ProductID=OD.ProductID
GROUP BY p.CategoryId )
SELECT * From Products
Any help would be fantastic! ( I'm using NORTHWND database btw)
I think what you need is
;WITH temp AS
(
SELECT p.CategoryId,
COUNT (DISTINCT OD.OrderID) as TotalNumberOfOrders
FROM [dbo].[Products] p
INNER JOIN [dbo].[Order Details] OD ON p.ProductID=OD.ProductID
GROUP BY p.CategoryId
)
SELECT p.ProductName,
Count(DISTINCT Od.OrderId) AS Total,
Count(DISTINCT Od.OrderId)*100/temp.TotalNumberOfOrders AS Percentage
FROM Products p
INNER JOIN [dbo].[Order Details] OD ON p.ProductId = OD.ProductId
INNER JOIN temp ON p.CategoryId = temp.CategoryId
GROUP BY p.ProductId, p.ProductName, temp.TotalNumberOfOrders
Remember Count(Distinct..) to count Order.
Using a sub-Query:
SELECT P.ProductName,
COUNT(OrderID) AS NumberOfOrders,
CAST((CAST(COUNT(OrderID) AS DECIMAL(9,2)) / CAST(Derived_Table.CNT AS
DECIMAL(9,2))) * 100 AS DECIMAL(9,2)) AS Percentage
FROM [Northwind].[dbo].[Order Details]
INNER JOIN dbo.Products AS P
ON [Order Details].ProductID = P.ProductID
INNER JOIN (SELECT COUNT(F.OrderID) AS CNT, P.CategoryID
FROM [Northwind].[dbo].[Order Details] F
INNER JOIN dbo.Products P
ON F.ProductID = P.ProductID
GROUP BY P.CategoryID) AS Derived_Table
ON P.CategoryID = Derived_Table.CategoryID
GROUP BY [Order Details].ProductID, P.ProductName, Derived_Table.CNT
ORDER BY [Order Details].ProductID

how could you rewrite this query doesn't use a sub query?

Since a sub query returns rows and columns, you can join against a sub query just like you can join against a normal table.
SELECT
P.ProductCode, I.QuantityInStock as Qty, P.Title, P.Price
FROM
Products as P
JOIN
(SELECT * FROM Inventory) as I on (P.ProductCode = I.ProductCode);
How could you rewrite this query so it doesn't use a sub query?
am trying to rewrite but am not sure is correct
SELECT P.ProductCode, I.QuantityInStock as Qty, P.Title, P.Price
FROM Products as P
WHERE Inventory as I on (P.ProductCode = I.ProductCode);
Is this correct?
SELECT P.ProductCode, I.QuantityInStock as Qty, P.Title, P.Price
FROM Products as P
JOIN Inventory as I on P.ProductCode = I.ProductCode;
Since you're selecting ALL columns from Inventory you can just do
SELECT
P.ProductCode, I.QuantityInStock as Qty, P.Title, P.Price
FROM
Products as P
JOIN
Inventory I on P.ProductCode = I.ProductCode;
SELECT P.ProductCode, I.QuantityInStock as Qty, P.Title, P.Price
FROM Products as P, Inventory as I
WHERE P.ProductCode = I.ProductCode

How do I select max date for each row from a subquery

Let's say I want to select the 3 bestsellers in a supermarket. To do this, I have to add each sale to get the total for each product:
SELECT TOP(3) *
FROM
(
SELECT
SUM(s.individual_sale) AS totalsales,
p.productID AS ID,
p.productName AS Name
FROM
sales s,
products p
WHERE
1=1
AND p.productID = s.productID
GROUP BY
p.productID,
p.productName
) AS top_sellers
ORDER BY
top_sellers.totalsales DESC
It then returns me something like this:
ID..|.Name.|.totalsales
55.|.milk....|.1000
24.|.candy.|.800
67.|.juice...|.500
Now I want to retrieve a 4th column containing the last sale from each of these items, like querying "MAX saledate" to each one. How do I accomplish that?
EDIT: Adding MAX(s.saledate) isn't helping. It retrieves a date like 01 Jan 2012 to all rows, but if I query MAX(s.saledate) individually for each entry of the table above, it returns the correct date... My question is, how can I add the column MAX(s.saledate) for each product, using the same query that shows the 3 bestsellers.
You could add max(s.saledate) to your query. The subquery is not needed. The syntax t1 join t2 on <predicate> is considered much more readable than from t1, t2 where <predicate>.
select top 3 sum(s.individual_sale) as totalsales
, p.productID as ID,
, p.productName as Name
, max(s.saledate) as MaxSaleDate
from sales s
join products p
on p.productID = s.productID
group by
p.productID
, p.productName
order by
sum(s.individual_sale) desc
SELECT TOP(3) *
FROM
(
SELECT
SUM(s.individual_sale) AS totalsales,
p.productID AS ID,
p.productName AS Name,
MAX(s.saledate) as MaxSaleDate
FROM
sales s,
products p
WHERE
1=1
AND p.productID = s.productID
GROUP BY
p.productID,
p.productName
) AS top_sellers
ORDER BY
top_sellers.totalsales DESC
Add MAX(saledate) to your exisitng query.
SELECT TOP(3) *
FROM
(
SELECT
SUM(s.individual_sale) AS totalsales,
p.productID AS ID,
p.productName AS Name,
MAX(saleDate)
FROM
sales s,
products p
WHERE
1=1
AND p.productID = s.productID
GROUP BY
p.productID,
p.productName
) AS top_sellers
ORDER BY
top_sellers.totalsales DESC