I've got some code with the partition function, but it's not working.
I get an error message that says
Incorrect syntax near 'Sales'
Does anyone know why? I looked at the other partition questions, didn't find an answer,
The code (below) is supposed to select PriceZoneID and Sales from the Aggregated Sales History table then sum up the total sales using the OVER function and put that data in a new column called Total Sales.
It should then sum up the sales for each zone using the OVER (PARTITION) expression in a new column called TotalSalesByZone then order the data by Price Zone ID and Sales
Select PriceZoneID,
Sales,
SUM(Sales) OVER () AS Total Sales,
SUM(Sales) OVER (PARTITION BY PriceZoneID) AS TotalSalesByZone
From AggregatedSalesHistory
ORDER BY PriceZoneID AND Sales;
(Partition By divides the result into Partitions eg Zones)
If you could post the code with the correct answer, it would be greatly appreciated!
Coming out of the comments now, as it's getting a little silly to correct the errors in there. There is 1 typograhical error in your code, and 1 syntax error:
Select PriceZoneID,
Sales,
SUM(Sales) OVER () AS Total Sales, --There's a space in the alias
SUM(Sales) OVER (PARTITION BY PriceZoneID) AS TotalSalesByZone
FROM AggregatedSalesHistory
ORDER BY PriceZoneID AND Sales; --AND is not valid in an ORDER BY clause
The correct query would be:
Select PriceZoneID,
Sales,
SUM(Sales) OVER () AS TotalSales, --Removed Space
SUM(Sales) OVER (PARTITION BY PriceZoneID) AS TotalSalesByZone
FROM AggregatedSalesHistory
ORDER BY PriceZoneID, Sales; --Comma delimited
Related
I am trying to find YTD and MTD totals for total sales. The total sales is derived by multiplying "Order Quantity" and "Unit price" and subtracting "Discount_Applied".
Here is my query,
select orderdate,datename(month,orderdate) as Mnth,year(orderdate) as YR, sum((unit_price*order_quantity)-discount_applied) as Total_Sales,
sum((unit_price*order_quantity)-discount_applied) over (partition by year(orderdate) order by orderdate) as YTD,
sum((unit_price*order_quantity)-discount_applied) over (partition by year(orderdate),datename(month,orderdate) order by orderdate) as MTD
from sales
group by orderdate,datename(month,orderdate),year(orderdate)
However, when I run this query, it gives me an error saying
Column 'sales.Unit_Price' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."
I guess it has something to do with the windows function I am using, but can't figure out specifically the problem. Can someone help.
When you use a window function, it is calculated after any possible GROUP BY aggregation. So those columns don't exist anymore, only the aggregation exists.
Instead, you need to SUM the SUM: you need to do a windowed sum over the aggregate sum.
SELECT
s.orderdate,
DATENAME(month, s.orderdate) as Mnth,
YEAR(s.orderdate) as YR,
SUM((s.unit_price * s.order_quantity) - s.discount_applied) as Total_Sales,
SUM(SUM((s.unit_price * s.order_quantity) - s.discount_applied) OVER
(PARTITION BY YEAR(s.orderdate) ORDER BY EOMONTH(s.orderdate), s.orderdate ROWS UNBOUNDED PRECEDING) as YTD,
SUM(SUM((s.unit_price * s.order_quantity) - s.discount_applied)) OVER
(PARTITION BY YEAR(s.orderdate), EOMONTH(s.orderdate) ORDER BY s.orderdate ROWS UNBOUNDED PRECEDING) as MTD
FROM sales s
GROUP BY
s.orderdate;
Note also that EOMONTH is a little more efficient than DATENAME, and that adding the month to the YTD ordering means it can use the same sort, without affecting the calculation.
Also ROWS UNBOUNDED PRECEDING is a little more efficient than the default RANGE UNBOUNDED PRECEDING.
I am exploring a dataset in Microsoft SQL Server Management, regarding sales.
I want to obtain the day with the highest number of items sold for each year, therefore a table like this (the values in the rows are totally random):
Year
Purchase Day
Max_Daily_Sales
2011
2011-11-12
48
2012
2012-12-22
123
I first tried to run this query:
WITH CTE_DailySales AS
(
SELECT DISTINCT
Purchase_Day,
Year,
SUM(Order_Quantity) OVER (PARTITION BY Purchase_Day, Year) AS Daily_Quantity_Sold
FROM
[sql_cleaning].[dbo].[Sales$]
)
SELECT
Year, MAX(Daily_Quantity_Sold) AS Max_Daily_Sales
FROM
CTE_DailySales
GROUP BY
Year
ORDER BY
Year
It partially works since it gives me the highest quantity of items sold in a day for each year. However, I would also like to specify what day of the year it was.
If I try to write Purchase_Day in the Select statement, it returns the max for each day, not the single day with the highest number of items sold.
How could I resolve this problem?
I hope I've been clear enough and thanks you all for your help
I suggest you use ROW_NUMBER to get you max value, your query would be:
WITH CTE_DailySales AS
(
SELECT Purchase_Day,
Year,
SUM(Order_Quantity) Daily_Quantity_Sold,
ROW_NUMBER() OVER(PARTITION BY Year ORDER BY SUM(Order_Quantity) DESC) as rn
FROM
[sql_cleaning].[dbo].[Sales$]
GROUP BY Purchase_Day,
Year
)
SELECT
*
FROM
CTE_DailySales
WHERE rn = 1
Simply :
SELECT Purchase_Day,
Year,
SUM(Order_Quantity) OVER(PARTITION BY Purchase_Day, Year) AS Daily_Quantity_Sold,
MAX(SUM(Order_Quantity)) OVER(PARTITION BY Purchase_Day, Year) AS MAX_QTY_YEAR
FROM [sql_cleaning].[dbo].[Sales$];
Please refer to the below query
SELECT sum(sales) AS "Sales",
sum(discount) AS "discount",
year
FROM Sales_tbl
WHERE Group by year
Now I want to also display a column for AVG(sales) that is the same value and based on the total of sales column
Output
Please advise
Use AVG() as a window function:
WITH t AS (
SELECT
SUM(sales) AS sales, SUM(discount) AS discount, year
FROM tbl_sales
GROUP BY year
)
SELECT *,AVG(sales) OVER w_total
FROM t
WINDOW w_total AS (RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
ORDER BY year;
The frame RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING is pretty much optional in this case, but it is considered a good practice to be as explicit as possible in window functions. So you're also able to write the query like this:
WITH t AS (
SELECT
SUM(sales) AS sales, SUM(discount) AS discount, year
FROM tbl_sales
GROUP BY year
)
SELECT *,AVG(sales) OVER ()
FROM t
ORDER BY year;
Demo: db<>fiddle
I would like to order the result by using the SUM(Revenue), Below is my code kindly help me fix it, Thank you
SELECT
EXTRACT(YEAR FROM Release_date) AS year_released, COUNT(Genre) AS number_of_comedy,SUM(Revenue)AS total_revenue
FROM
Movie_data.movie
WHERE
Genre='Comedy'
GROUP BY
EXTRACT(YEAR FROM Release_date)
ORDER BY
SUM(Revenue)
LIMIT
1000
THE ERROR MESSAGE I get is "SELECT list expression references column Release_date which is neither grouped nor aggregated at [2:19]"
You should be able to use what you have written. You can also write:
ORDER BY total_revenue
Often when ordering by revenue, you want the largest values first:
ORDER BY total_revenue DESC
I am trying to find how I can calculate Percentage from table below
From the above table, I am hoping to get the data with percentage like below. However my SQL statement below returns all percentage value to 0. Please advise what I missed. Thanks
Select SupplierID
, ProductID
, Month
, Year
, Count(SupplierID) AS TotalSales
, (count(SupplierID)* 100/(Select Count (*) From ProductOrder)) AS Percentage
From ProductOrder
Order by Year DESC, Month DESC
That's integer division. Both operands to the division are integers, so the result is given as integer as well; 3/4 is 0, not 0.75. To work around this, just turn one of the arguments to a decimal.
I would also recommend using window functions rather than a subquery:
select supplierid, month, year,
count(*) as totalsales,
100.0 * count(*) / sum(count(*)) over(partition by month, year) as percentage
from productorder
group by supplierid, month, year
order by year desc, month desc, supplierid
Notes:
your original code is not a valid aggregation query to start with: it is missing a group by clause
your sample data indicates that you want the ratio per supplier against the total of the month and year, while your query (attempts to) compute the overal ratio; I fixed that too