Calculate MRR Kpi without monthly invoices - mysql

I am trying to calculate mrr for each month.
The DB table 'boxes' looks like this:
project_id
product_id
payment_method_id
price
interval
booked_at
canceled_at
1
1
3
19.00
1
2020-12-01 00:00:00
NULL
1
2
3
39.00
1
2020-05-01 00:00:00
2020-11-05 19:10:27
4
1
3
39.00
12
2020-05-01 00:00:00
2020-11-05 19:10:27
Payment-Interval is in months. I need to show in KPI dashboard the mrr.
Currently I have this query:
SELECT DATE_FORMAT(booked_at, '%Y-%m') AS period, sum(price)
FROM
project_boxes
GROUP BY period;
The problem with the above query is that it doesn't show between months MRR and doesn't work with canceled boxes.
What am I missing? Any help is appreciated.

Related

Mysql / Big Query to Find when a customer loses access for the first time (Gap / Island)

I'm hoping the query will work both in Mysql and BigQuery
For each customer I need to find the first date they had a subscription and the first date that they stopped having any subscriptions (e.g. a break in subscription). A customer can have multiple overlapping subscriptions. Once a customer stops having access then future subscriptions are not considered.
This is a sample table with a few rows. The actual table will have millions of rows and thousands of customers.
using this sample data:
select * from test_sub order by customer_id, effect_date, expire_date;
subscription_id
customer_id
effect_date
expire_date
1
1
2022-01-01 00:00:00
2022-03-01 00:00:00
2
2
2021-01-01 00:00:00
2021-03-01 00:00:00
3
2
2021-02-01 00:00:00
2021-04-25 00:00:00
4
2
2021-05-01 00:00:00
2021-06-01 00:00:00
5
2
2021-08-01 00:00:00
2022-10-01 00:00:00
The answer should be:
customer_id
min(effect_date)
max(expire_date)
1
2022-01-01 00:00:00
2022-03-01 00:00:00
2
2021-01-01 00:00:00
2022-04-25 00:00:00

Return customer id which didn't had any transactions in past 2 months using SQL query

I'm facing an issue while creating a sql query where I want transaction details which is older than 2 months. Can someone help me with this.
Basically, I have two table one transaction tables and one customer table.
For each customer there is record of transactions in transaction table. So, now I want a query which can retrieve all the customer_ids which didn't have any transactions in past 2 months.
Customers
id
name
1
Google
2
Facebook
3
Hooli
4
Yahoo!
Transaction
id
transaction_date
customer_id
1
2022-04-10
1
2
2022-04-05
1
3
2022-03-09
1
4
2022-03-24
1
5
2022-02-23
2
6
2022-02-22
2
7
2022-02-21
2
8
2022-03-24
2
9
2022-03-24
3
10
2022-01-23
4
11
2022-01-22
4
12
2022-01-21
4
Output
Customer_id=4(since it do not have any transactions in past 2 months)
Thank you
You can use the MySQL INTERVAL in your select query. Like this:
SELECT customer_id FROM `transaction`
GROUP BY customer_id
HAVING (CURDATE() - INTERVAL 2 MONTH) > MAX(transaction_date);
OUTPUT
customer_id
-------------
4
This query is based on the MAX(transaction_date) of the customer.

Group by dates using a different table date range

I am trying to get the sum of costs by date, if the date lies between the start and end date which is coming in from a different table.
To explain:
Table 1
id
date
cost
1
2020-02-02
$10
2
2020-03-05
$100
1
2020-03-10
$200
3
2020-07-16
$200
1
2019-01-01
$50
1
2019-02-10
$50
3
2012-10-01
$500
Table 2
id
start_date
end_date
1
2020-01-01
2020-12-31
3
2020-01-01
2020-11-15
2
2020-01-01
2021-01-31
I just want to aggregate the costs by month only if the date in table 1 lies within the start and end date of table 2. So here I want the output to look like:
date
cost
2020-01-31
$10
2020-02-29
$10
2020-03-31
$300
2020-04-30
-
2020-05-31
-
2020-06-30
-
2020-07-31
$200
2020-08-31
-
2019-09-30
-
2019-10-31
$500
2019-11-30
-
2019-12-31
-
What I have tried so far:
select sum(cost), last_day(date)
from table1 inner join table2
on table1.id=table2.id
and table1.date>=table2.start_date and table1.date<=table2.end_date
group by last_day(date)
select year(date) as year,month(date) AS month, sum(cost) AS cost
from table1 inner join table2
on table1.id=table2.id
and table1.date>=table2.start_date and table1.date<=table2.end_date
group by table1.id, year(date), month(date)
order by last_day(date)

how can i summarize some data in a MySQL table based on subsets of data determined by a datetime field?

Lets say i have this table:
id name date qty
1 bananas 2020-04-01 00:00:00 20
2 apples 2020-04-02 00:00:00 15
3 apples 2020-04-05 00:00:00 15
4 bananas 2020-04-06 00:00:00 10
5 bananas 2020-04-15 00:00:00 40
6 bananas 2020-04-16 00:00:00 20
7 apples 2020-04-17 00:00:00 15
8 apples 2020-04-17 00:00:00 5
What i want to achieve is a result set with total quantity of each fruit before 2020-04-06 in a InitialStock field and total quantity of each fruit after 2020-04-17 as FinalStock
It looks like you want conditional aggregation:
select
name,
sum(case when date <= '2020-04-06' then qty end) initial_stock,
sum(case when date >= '2020-04-17' then qty end) final_stock
from mytable
group by name
For each name, this gives you the sum of qty before April 4th and after Apri 17th, in two separated columns.

Daily count of Active Users for a given date range

I need to find the Daily total count of Active Users based on the Start Date and End Date.
REGISTRATION TABLE
id registration_no start_date end_date
1 1000 2014/12/01 2014/12/03
2 1001 2014/12/01 2014/12/03
3 1002 2014/12/02 2014/12/04
4 1003 2014/12/02 2014/12/04
5 1004 2014/12/02 2014/12/04
6 1005 2014/12/03 2014/12/05
7 1006 2014/12/05 2014/12/06
8 1007 2014/12/05 2014/12/09
9 1008 2014/12/06 2014/12/10
10 1009 2014/12/07 2014/12/11
The result should be in the following format.
Date Active Users
2014-12-01 2
2014-12-02 5
2014-12-03 6
2014-12-04 4
2014-12-05 3
2014-12-06 3
2014-12-07 3
2014-12-08 3
2014-12-09 3
2014-12-10 2
2014-12-11 1
2014-12-12 0
I know the following query is not working.
SELECT start_date, count(*) FROM registration
WHERE start_date >= '2014/12/01' AND end_date <='2014/12/12'
GROUP BY start_date
Which is not the desired output :
2014-12-01 2
2014-12-02 3
2014-12-03 1
2014-12-05 2
2014-12-06 1
2014-12-07 1
Any help would be much appreciated.
You need to create a "calendar" with all the days you need and then use a query like:
SELECT calDay as `Date`, count(id) as `Active Users`
FROM (SELECT cast('2014-12-01' + interval `day` day as date) calDay
FROM days31
WHERE cast('2014-12-01' + interval `day` day as date) < '2014-12-12') calendar
LEFT JOIN registration on (calDay between start_date and end_date)
GROUP BY calDay
ORDER BY calDay;
You can see it working in this fiddle, where days31 is just a view with integers 0-30. This allows the query to work in any calendar up to a period of 31 days. You can add more days to the view or generate them on the fly using cross joins. See http://www.artfulsoftware.com/infotree/qrytip.php?id=95
Try it.... please note on where condition FOR 2014-12-02, as per comment
SELECT DATE_FORMAT(start_date,'%Y-%m-%d')as Date, count(*) as ActiveUser FROM registration
WHERE (start_date >= '2014/12/02' AND end_date <='2014/12/02')
GROUP BY start_date