How to calculate the rank in mysql - mysql

I need to calculate the rank in mysql. Suppose I have list of sum of my product sales values of entire month then i need to rank the product from highest sales value in order to rank like 1 ,2 ,3 etc
Month Product Sum of Sales
Jan Latop 450000
jan Latop 150000
Jan Latop 250000
Feb Desktop 200000
Feb Desktop 150000
Feb Desktop 180000
so from above data output will be like
Month Product Sum of Sales rank
Jan Latop 450000 1
Jan Latop 250000 2
jan Latop 150000 3
Feb Desktop 200000 1
Feb Desktop 180000 2
Feb Desktop 150000 3

You can do something like this:
SELECT month,product,sumOfSales, #curRank := #curRank + 1 AS rank
FROM products p, (
SELECT #curRank := 0
) q
ORDER BY sumOfSales DESC;
I am assuming the table name is product and column name is sumOfSales.

You Can use this Query
SELECT sales FROM TABLE Order by sales DESC
sales is your column name where sum of sale is stored
Query Will Return Record with most sales first and so on.

Related

Month on month retention in a year in SQL

How can we calculate the month on month cumulative retention rate in SQL
Bill_Date Customer_id
2021-01-01 1
2021-01-23 2
2021-01-29 3
2021-02-17 1
2021-02-19 2
2021-03-01 3
Retention Rate= (Total Number of unique Customers in present Month)/(Total Number of Customers in previous Months)
Expected Output
January : 100%
February : 66.7%
March : 25%
February =(Unique customers in feb)/((Unique customers in jan)
March=(Unique customers in march)/((Unique customers in jan)+(Unique
customers in feb)
Consider a window function for cumulative sum of unique customer per year/month:
WITH sub AS (
SELECT YEAR(c.Bill_Date) AS bill_year,
MONTH(c.Bill_Date) AS bill_month,
COUNT(DISTINCT c.customer_id) AS unq_customers
FROM customer_bills c
GROUP BY YEAR(c.Bill_Date),
MONTH(c.Bill_Date)
)
SELECT bill_year,
bill_month,
unq_customers,
IFNULL(
unq_customers /
(SUM(unq_customers) OVER(ORDER BY bill_month) -
unq_customers),
1
) * 100 AS retention_rate
FROM sub
Online Demo

issues writing simple sql queries

I have recently started working with SQL and I am trying to write a query that will display all cities that has the highest volume and listing on a yearly basis.
this query is able to handle the year 2011 alone
select city, year, month,max(volume),max(listings)
from kaydata
where year = 2011
result
city year month max(volume) max(listings)
0 Abilene 2011 2 6505000.0 746.0
sample data
city year month volume listings
0 modak 2011 1 5380000.0 701.0
1 Abilene 2011 2 6505000.0 746.0
2 ipetu 2010 3 9285000.0 784.0
2 oyog 2010 4 7085000.0 204.0
desired result
city year month max(volume) max(listings)
0 Abilene 2011 2 6505000.0 746.0
1 ipetu 2010 3 9285000.0 784.0
If I understand correctly, this would achieve what you're after:
select city,year,month,volume,maxlisting from (
select * , row_number() over (partition by year order by volume desc) rn
, max(listing) over (partition by year) maxlisting
from kaydata
) t
where rn = 1

Incrementing a column for each rows from two queries

I have two queries that give respectively the number of working unit bought, and the number of working unit consumed by a client.
I am working on a SQL Server 2014
The WUBought query returns something like this example :
Customer Year Month UnitBought
Cust1 2015 6 50
Cust2 2014 7 100
Cust1 2013 10 30
Cust3 2015 2 40
The other query returns the number that were consumed by a client :
Customer Year Month UnitConsumed
Cust1 2015 2 6
Cust1 2015 5 20
Cust2 2015 3 8
Cust1 2015 4 3
Cust3 2015 2 10
What I am basically trying to do, is a sum of what has been bought for every month, minus what has been consumed. Here is an example of what I want as a result for the first six months for Cust1 :
Customer Year Month Remaining
Cust1 2015 1 30
Cust1 2015 2 24
Cust2 2015 3 24
Cust1 2015 4 21
Cust3 2015 5 1
Cust3 2015 6 51
The query that returns the WU bought with a UNION ALL from a table that lists every month, to get each month even if there is no value :
SELECT Customer, [Year], [Month], SUM(UOBought) AS UORest
FROM WU_Bought
GROUP BY [Customer], [PurchaseDate]
UNION ALL
SELECT '' AS Customer, [Year], [Month], '' AS UORest
FROM Months
GROUP BY [Year], [Month]
Here is the query that sums every bought unit every month, with the same union statement :
SELECT Customer, [Year], [Month], SUM(TotalConsumed) * -1 AS UORest
FROM WUConsumed
GROUP BY Customer, Year, Month
UNION ALL
SELECT '' AS Customer, [Year], [Month], '' AS UORest
FROM EveryMonths
GROUP BY Year, Month
Right now I think I must adjust the first one, forcing it to keep the previous sum, but I am not sure how I can do that.
Does this work for you?
SELECT b.customer_id, b.year, b.month, SUM(b.units_bought) AS units_bought, ISNULL(c.units_consumed,0) AS units_consumed, SUM(b.units_bought) - ISNULL(c.units_consumed,0) AS units_remaining
FROM Bought b
LEFT JOIN Consumed c
ON b.customer_id = c.customer_id AND b.year = c.year AND b.month = c.month
GROUP BY b.customer_id, b.year, b.month
Ok, I got it working.
What I did was really "simple", using a SQL Server feature, available since 2012 :
ROWS UNBOUNDED PRECEDING
Here is a pretty clear article about this feature.
I created an other view grouping the results from the queries about consumed and bought units with a UNION ALL clause, called "WU_Closing_View", then used the ROWS UNBOUNDED PRECEDING within it :
SELECT Customer, Year, Month, SUM(Closing) OVER(PARTITION BY Customer ORDER BY Year, Month ROWS UNBOUNDED PRECEDING) AS Closing
FROM WU_Closing_View
GROUP BY Customer, Year, Month, Closing
UNION ALL
SELECT '' AS Customer, Year, Month, '' AS Sum_bought
FROM Months
GROUP BY Year, Month
ORDER BY Customer, Year, Month
Note that I used PARTITION BY, in order to sum by client. Because I wanted to show every month in a SSRS matrix, I added a "UNION ALL" pointing to a table that has every year and month on it for an empty client, from 2010 to 2017. But it is optional if you don't need the evolution for every month.
There may be an easier way, but that's the one I found so far.

How to pass parameters in subquery mysql?

So, I have a mysql table with user id(id) and date of transaction(dot) that looks like:
id dot
-------------------------------
101 2015-06-12 12:18:42 UTC
102 2015-06-12 12:18:40 UTC
103 2015-06-12 12:18:42 UTC
101 2015-07-12 12:18:42 UTC
and so on.
(Output for this data should be:
Year Month Num of users
-----------------------------
2015 06 0
2015 07 2
)
It logs all the transactions that are made. For each month m, I want to find out the count of users by month and year who transacted in m-1 month but not in m month. The results need to be grouped by year and month. Ideally, table should look like (http://sqlfiddle.com/#!9/b80f49/1)
Year Month Num of users
-----------------------------
2015 05 0
2015 06 2
2015 07 1
2015 08 4
Now for a single month(E.g. 05/2015), I can hardcode:
SELECT "2015" AS Year,"05" AS Month, "COUNT(DISTINCT id) FROM table WHERE
MONTH(dot)=4 AND YEAR(dot)=2015
AND id NOT IN
(SELECT id FROM table WHERE MONTH(dot)=5 AND YEAR(dot)=2015)
To group the count of users using GROUP BY, the query would look like:
SELECT YEAR(dot) as Year,MONTH(dot),COUNT(DISTINCT id) as Month FROM table
WHERE id NOT IN(SELECT id FROM table
WHERE DATEDIFF(dot_parent,dot_this_table)<30 AND DATEDIFF(dot_parent,dot_this_table)>=0)
Here dot_parent is the dot of the parent query and dot_this_table is the dot of the subquery. Now the problem here is that I can't pass the dot_parent inside the subquery. Is there a way to do that or frame the query in another way such that its logical structure remains similar, since I would have to make similar queries for multiple date ranges.
You must query the same table thrice: once for the months to show, once to find the users in the previous months, once for user matches in the months in question. You'd select distinct users per month, as you are not interested in whether a user had more than one transaction in a month or not.
Here is the complete query:
select
this_month.year,
this_month.month,
count(prev_month_users.user) - count(this_month_users.user) as users
from
(
select distinct year(timing) as year, month(timing) as month
from transactions
) this_month
left join
(
select distinct
year(timing) as year, month(timing) as month, id as user,
year(date_add(timing, interval 1 month)) as next_month_year,
month(date_add(timing, interval 1 month)) as next_month_month
from transactions
) prev_month_users
on prev_month_users.next_month_year = this_month.year
and prev_month_users.next_month_month = this_month.month
left join
(
select distinct year(timing) as year, month(timing) as month, id as user
from transactions
) this_month_users
on this_month_users.user = prev_month_users.user
and this_month_users.year = prev_month_users.next_month_year
and this_month_users.month = prev_month_users.next_month_month
group by this_month.year, this_month.month;
Result:
year month users
2015 5 0
2015 6 2
2015 7 1
2015 8 3
Note that I show three users for August (users 101, 102, 104). User 101 had two transactions in July, but it is still three users who had transactions in July but not in August.
Here is your SQL fiddle back: http://sqlfiddle.com/#!9/b80f49/13

how can i show sql header columns in rows in sql server

i want to show these records column wise for particular month and year, like below table format
Source Total
Organic 1252
Paid 121
Email Campaign 121
Total 1494
select Organic,Paid ,EmailCampaign ,Total from tbl_leads where Month='Aug' and Year='2015'
below is sample date
Organic Paid EmailCampaign Total ProjectName Month Year
4444 5555 2222 1111 demo project Feb 2015
1252 121 121 1494 debug test Aug 2015
In Sql Server you can use Cross Apply with Tabled Valued Constructor to unpivot the data
SELECT cs.Source,
cs.Total
FROM tbl_leads
CROSS apply (VALUES ('Organic',Organic),
('Paid',Paid),
('EmailCampaign',EmailCampaign),
('Total',Total)) cs(Source, Total)
WHERE Month = 'Aug'
AND Year = '2015'
Or Generic Sql solution
SELECT 'Organic' AS Source,
Organic AS Total
FROM tbl_leads
UNION ALL
SELECT 'Paid',
Paid
FROM tbl_leads
UNION ALL
SELECT 'EmailCampaign',
EmailCampaign
FROM tbl_leads
UNION ALL
SELECT 'Total',
Total
FROM tbl_leads