Mysql and make cumulative count - mysql

I have a clients mysql table and I´d like to get a cumulatie count of clients grouped by month-year.
I have tried the next, but no look:
SELECT DATE_FORMAT(datacad,'%m-%y') AS month-year, count(id) OVER(ORDER BY id) AS cumulative_count
FROM clients;
clients
-------
id datacad
1 2001-10-10
2 2001-10-11
3 2002-11-12
4 2001-12-14
5 2003-12-15
6 2003-12-16
7 2003-12-17
//required result
month-year cumulative_count
----------------------------
10-2001 3
11-2002 4
12-2003 10
Additional Info:
When I use:
SELECT DATE_FORMAT(datacad,'%m-%y') AS label, count(*) as total FROM clients
GROUP BY label
order by datacad
I get:
label,total
03-2011,1
04-2011,1268
05-2011,1365
06-2011,1244
07-2011,1102
08-2011,315
02-2013,1
03-2013,1
03-2014,1
06-2014,1
07-2014,1
01-2017,1
02-2017,1
01-2018,4
05-2018,2
08-2018,1
09-2019,1
04-2020,3
06-2020,1
But when I use:
SELECT DATE_FORMAT(datacad,'%m-%y') AS month_year,
SUM(COUNT(id)) OVER (ORDER BY id) AS cumulative_count
FROM clients
GROUP BY month_year
ORDER BY MIN(datacad);
I get:
month_year,cumulative_count
03-11,1271
04-11,1268
05-11,2636
06-11,3880
07-11,4982
08-11,5297
02-13,5298
03-13,5299
03-14,5300
06-14,5301
07-14,5302
01-17,5303
02-17,5304
01-18,5308
05-18,1270
08-18,5309
09-19,5310
04-20,5313
06-20,5314
The results from both don´t match.

You need a GROUP BY and to SUM() the counts for a cumulative sum:
SELECT DATE_FORMAT(datacad,'%m-%y') AS month_year,
SUM(COUNT(id)) OVER (ORDER BY MIN(datacad)) AS cumulative_count
FROM clients
GROUP BY month_year
ORDER BY MIN(datacad);
I also assume you want the data in date order, so I added an ORDER BY.

Related

Trying to utilize a window function instead of this script

I'm trying to improve my query for this topic at hand. I'm trying to find the top 5 and bottom 5 growth rates per state from 2020 to 2021 in my org. The table has the columns as specified: orderid, orderdate, totaldue, state, etc. (these are probably the most important columns). This is the query I created so far, while it works I think it would be more efficient if I was able to implement a window function instead.
SELECT state, SUM(TotalDue) as sum
into #temp2020
from table
where OrderDate like "2020%"
group by StateProvince
order by sum desc;
SELECT state, SUM(TotalDue) as sum
into #temp2021
from table
where OrderDate like "2021%"
group by StateProvince
order by sum desc;
--top 5 growth rates--
select #temp2020.state, ((#temp2021.sum-#temp2020.sum)/#temp2020.sum) as 'growthrate'
from #temp2020
join #temp2021 on #temp2021.state = #temp2020.state
order by growthrate desc limit 5
--bottom 5 growth rates--
select #temp2020.state, ((#temp2021.sum-#temp2020.sum)/#temp2020.sum) as 'growthrate'
from #temp2020
join #temp2021 on #temp2021.state = #temp2020.state
order by growthrate asc limit 5
drop table if exists #temp2020
drop table if exists #temp2021
You could use DENSE_RANK here:
WITH cte AS (
SELECT state, SUM(TotalDue) AS sum,
DENSE_RANK() OVER (ORDER BY SUM(TotalDue)) rnk_asc,
DENSE_RANK() OVER (ORDER BY SUM(TotalDue) DESC) rnk_desc
FROM yourTable
WHERE YEAR(OrderDate) IN (2020, 2021)
GROUP BY state
)
SELECT state, sum
FROM cte
WHERE rnk_asc <= 5 OR rnk_desc <= 5
ORDER BY state, sum;

How to get and count the row of table in SQL

Initially I have a data sheet like this
What I want is that after using the SQL the SQL will produce a table like this
I have just learned SQL, have tried count () and group by but not yet.
The TOTAL column will be counted based on the SIZE and NAME columns.
First you want to format your date accordingly using DATE_FORMAT(date, "%Y-%m") to get the format 2021-03. Then you can use GROUP BY along with COUNT(*).
SELECT
name,
size,
DATE_FORMAT(date, "%Y-%m") as month,
COUNT(*) as Total
FROM test
GROUP BY
name,
size,
DATE_FORMAT(date, "%Y-%m")
ORDER BY
COUNT(*) DESC,
name ASC;
name
size
month
Total
A
1
2021-03
2
B
2
2021-03
2
A
2
2021-03
1
C
3
2021-03
1
Working example at https://www.db-fiddle.com/f/7edM78Qhp8wLZ1JJZoE3bH/1
It's not clear what order you want the results returned in, so you can change the ORDER BY clause to customize it how you want.
select Name,Size,Cast(date as date) as Date,count(1) from tablename
group by Name,Size,Cast(date as date)

Using SUM for first n rows in each group in SQL

I have one table with two columns (client_id and spent). Each client bought something more than 20 times. I want to sum spendings for each client.
I know that I can use sum and group by to do that, but I want to use sum not for all values in the groups but for only first 10 values. How can I do that?
I have tried with top 10 and limit 10, but It does not work.
I have 10 different clients and more than 200 rows. Clients are not scattered, they are in order, so I have 20 rows on client1 than 20 rows of on client2... Each client appears more than 20 times. I want to use sum and group by, but I do not want to sum all values (more than 20 for each row) , i want to sum first 10 values. Its ordered by time for each client
select client_id, sum(spendings)
from my_table
group by client_id
If you are using Mysql 8.0, You can do this by using window function.
select client_id, sum(spendings)
from (select client_id, spendings, row_number() over (partition by client_id order by <timecol>) rn
from my_table) t
where rn < 11
group by client_id
For MySQL, try this following code-
SELECT client_id,SUM(spendings)
FROM
(
select client_id,
spendings,
#row_num :=IF(client_id = #client_id,#row_num+1,1)AS RowNumber,
#client_id := client_id
FROM my_table
ORDER BY client_id
-- You may need to add here appropriate ordering
-- To get your desired 10 rows for group by in the result
)A
WHERE A.RowNumber < 11
GROUP BY client_id

How to get the id of highest total from all groups? (MySQL)

Suppose i have following table
id Salary
1 5
2 3
1 3
1 6
2 5
3 5
3 2
4 1
4 3
2 9
I want to get the id of highest total(sum) salary from all groups. In this case the result should be id=2 sum=17( i.e. 3+5+9 = 17)
If you really only expect/need a single id group, then using LIMIT is probably the most straightforward approach here:
SELECT id, SUM(Salary) AS total
FROM yourTable
GROUP BY id
ORDER BY SUM(Salary) DESC
LIMIT 1;
If there could be ties for the highest salary, then we would need to do more work. Before MySQL 8+, the query given by #MKhalid is what we would need to do. Starting with MySQL 8+, we can use the RANK analytic function:
SELECT id, total
FROM
(
SELECT id, SUM(Salary) AS total,
RANK() OVER (ORDER BY SUM(salary) DESC) rank
FROM yourTable
GROUP BY id
) t
WHERE rank = 1;
WITH CTEName AS
(SELECT id, SUM(salary) as total_salary from testTable
GROUP BY id )
select top 1 id from CTEName ORDER BY total_salary desc

Most common number in MYSQL SELECT statement

I am trying to get a MYSql statement to spit out the most common number in a field. I believe I am supposed to use COUNT(QUANTITY) but I am confused by which to GROUP BY and ORDER BY, I can't seem to get the correct MODE (Most common number).
*EDIT*
Here is a sample table:
QUANTITY | ORDER_NUMBER
1 51541
4 12351
5 11361
5 12356
6 12565
8 51424
10 51445
25 51485
The MYSql statement should spit out the number 5 because it appears most often
SELECT QUANTITY,COUNT(*)
FROM ...
GROUP BY 1
ORDER BY 2 DESC
LIMIT 1;
SELECT ORDER_NUMBER AS ORDER, COUNT(QUANTITY) as numorders
FROM table
GROUP BY ORDER_NUMBER
ORDER BY numorders
to get the top 10 order_numbers do
select order_number, count(order_number) as quantity
from your_table
group by order_number
order by quantity desc
limit 10
SELECT QUANTITY, COUNT(QUANTITY) AS TOTAL_Q
FROM MYTABLE
GROUP BY QUANTITY
ORDER BY TOTAL_Q DESC
this will give you number of quanity from most to least number....