I'm trying to output a top 3 products per quarter, that should be a total of 12 rows, since 3 top products per quarter.
Closest output is the one provided below i have no idea how to like partition it every quarter
SELECT * FROM (SELECT QUARTER, PRODUCT_NAME, SUM(QUANTITY) "QTY_SOLD", SALES, SUM(PROFIT) "PROFIT_GENERATED" FROM DELIVERIES_FACT
WHERE EXTRACT(YEAR from SHIP_DATE) = 2015 GROUP BY QUARTER, PRODUCT_NAME, SALES ORDER BY "PROFIT_GENERATED" DESC)
WHERE rownum <= 3
getting an output of
I've written this SQL extracting the calendar quarter from SHIP_DATE; you can adjust as needed.
Similarly, RANK(), ROW_NUMBER(), and DENSE_RANK() all are different; you may wish to experiment with each analytical function to see which best fits your data and handles ties the way you want them to.
SELECT *
FROM (SELECT RANK() OVER (PARTITION BY SHIP_QUARTER
ORDER BY PROFIT_GENERATED desc) AS PROFIT_RANK_BY_Q,
ORIG.*
FROM
(SELECT EXTRACT(QUARTER from SHIP_DATE) AS SHIP_QUARTER,
PRODUCT_NAME,
SUM(QUANTITY) "QTY_SOLD", SALES, SUM(PROFIT) "PROFIT_GENERATED"
FROM DELIVERIES_FACT
WHERE EXTRACT(YEAR from SHIP_DATE) = 2015
GROUP BY EXTRACT(QUARTER from SHIP_DATE), PRODUCT_NAME, SALES
)
)
WHERE PROFIT_RANK_BY_Q <= 3
order by SHIP_QUARTER, PROFIT_RANK_BY_Q
Related
I have a question about ranking . (My using Pgadmin for my SQL codes)
Mange to get my sum of sales in DESC order and rank 1 to 3 for the month of APR
But how can I achieve my result by showing only rank 1 to 3 for the month of Apr , May and June.
I need to reflect only 9 rows in my table .
SELECT restaurant_id,
EXTRACT(year FROM submitted_on) AS year,
EXTRACT(month FROM submitted_on) AS month,
SUM(total_amount),
RANK() OVER (PARTITION BY(extract(month from submitted_on))
ORDER BY SUM(total_amount) DESC) rank
FROM orders
WHERE submitted_on::date BETWEEN '2021-04-01' AND '2021-06-30'
GROUP BY restaurant_id, year, month
If you just want 3 records you should use row_number instead of rank. for your requirement you can do it in this way:
select t.* from (
SELECT restaurant_id,
EXTRACT(year FROM submitted_on) AS year,
EXTRACT(month FROM submitted_on) AS month,
SUM(total_amount),
RANK() OVER (PARTITION BY(extract(month from submitted_on))
ORDER BY SUM(total_amount) DESC) rank
FROM orders
WHERE submitted_on::date BETWEEN '2021-04-01' AND '2021-06-30'
GROUP BY restaurant_id, year, month
) t
where rank <=3;
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$];
I have the following query that shows total sales for each product on an hourly basis. However, it is very big data and I don't want to see all products, so would like to see the top 1000 product_id based on sales for each date, hour, and category_id dimensions.
SELECT date,
hour,
category_id,
product_id,
sum(sales) AS sales
FROM a
LEFT JOIN
ON a.product_id = b.product_id
WHERE date(date) >= date('2021-01-01')
GROUP BY 1, 2, 3, 4
How to do it in the Athena?
Thanks in advance.
You can use rank function on your result and then filter out corresponding ranks:
SELECT date,
hour,
category_id,
product_id,
sales
FROM
(
SELECT *,
rank() OVER (PARTITION BY date, hour, category_id
ORDER BY sales DESC) AS rnk
FROM (your query)
)
WHERE rnk <= 1000
I have a SQL Server database with a table containing sales. I need to create a report that will show me products and their average selling price for the past 3 months, which would look something like that:
SELECT product_code, product_description, ROUND((SUM(sales_value)/3),0) as avg3
FROM sales_data
WHERE sales_period >= dateadd(mm, datediff(mm, 0, getdate()) - 3, 0)
GROUP BY product_code, product_description;
--sales_period is always 1st of month, ie. 2021-02-01
here is the catch: this has to be an average of last 3 months where there was actually a sales.
For example, since we are currently in March:
product ABC had no sales in January, so I will have to get values
from November, December & February.
product XYZ, had no sales in November & December, so I need to get
the data from October, January and February.
Any idea how to crack this one?
Thanks in advance.
If you need the last three months for each product, then use dense_rank():
SELECT product_code, product_description,
ROUND((SUM(sales_value) / 3),0) as avg3
FROM (SELECT sd.*,
DENSE_RANK() OVER PARTITION BY product_code ORDER BY YEAR(sales_period) DESC, MONTH(sales_period) DESC) as seqnum
FROM sales_data sd
) sd
WHERE seqnum <= 3
GROUP BY product_code, product_description;
Note: Some product may not have 3 months of sales. So I might suggest two levels of aggregation:
SELECT product_code, product_description,
AVG(month_sales) as avg3
FROM (SELECT product_code, product_description,
YEAR(sales_period) as yyyy, MONTH(sales_period) as mm,
SUM(sales_value) as month_sales,
DENSE_RANK() OVER PARTITION BY product_code ORDER BY YEAR(sales_period) DESC, MONTH(sales_period) DESC) as seqnum
FROM sales_data sd
GROUP BY product_code, YEAR(sales_period), MONTH(sales_period)
) sd
GROUP BY product_code, product_description;
I have a question that is asking:
-List the max sales for each year?
I think I have the starter query but I can't figure out how to get all the years in my answer:
SELECT TO_CHAR(stockdate,'YYYY') AS year, sales
FROM sample_newbooks
WHERE sales = (SELECT MAX(sales) FROM sample_newbooks);
This query gives me the year with the max sales. I need max sales for EACH year. Thanks for your help!
Use group by and max if all you need is year and max sales of the year.
select
to_char(stockdate, 'yyyy') year,
max(sales) sales
from sample_newbooks
group by to_char(stockdate, 'yyyy')
If you need rows with all the columns with max sales for the year, you can use window function row_number:
select
*
from (
select
t.*,
row_number() over (partition by to_char(stockdate, 'yyyy') order by sales desc) rn
from sample_newbooks t
) t where rn = 1;
If you want to get the rows with ties on sales, use rank:
select
*
from (
select
t.*,
rank() over (partition by to_char(stockdate, 'yyyy') order by sales desc) rn
from sample_newbooks t
) t where rn = 1;