Count Distinct Active users per month - mysql

I am trying to calculate active monthly users based on signup and cancel dates. Several users have NULL cancel dates (since still active). This query has a bunch of users as just null action_year and action_month.
SELECT
T.action_year,
T.action_month,
COUNT(USerID) active_users
FROM
(
SELECT DISTINCT UserID, YEAR(SignupDate) action_year, MONTH(SignupDate) action_month FROM Stat
UNION
SELECT DISTINCT UserID, YEAR(CancelDate) action_year, MONTH(CancelDate) action_date FROM Stat
) T
GROUP BY
T.action_year,
T.action_month
ORDER BY
T.action_year ASC,
T.action_month ASC

Presumably active users are those where the month is somehow between the signup and cancel dates. This is tricky to define. Is it active on any date of the month? Active on the last day? Active on the first day?
I will assume the first. Active on any day during the month.
The idea is that the number of actives in a given month are all people who have signed up previously and not yet stopped. Given this observation, the calculation proceeds as follows:
Get a list of all years and months. The following query assumes that signups occur every month to simplify this part.
Use a correlated subquery to get the number of actives. This will do comparisons to the "yyyymm" form of the date.
Be sure to remember that CancelDate can be NULL.
The resulting query is:
select ym.the_year, ym.the_month,
(select count(*)
from stat s
where date_format(SignupDate, '%Y-%m') <= ym.yyyymm and
(CancelDate is null or date_format(CancelDate, '%Y-%m') >= ym.yyyymm)
) as NumActives
from (select distinct year(SignupDate) as the_year, month(SignupDate) as the_month,
date_format(SignupDate, '%Y-%m') as yyyymm
from stat
) ym

Related

Who to the number of users who have had one transaction per day?

Here is my query:
select count(1) from
(select count(1) num, user_id from pos_transactions pt
where date(created_at) <= '2020-6-21'
group by user_id
having num = 1) x
It gives me the number of users who have had 1 transaction until 2020-6-21. Now I want to group it also per date(created_at). I mean, I want to get a list of dates (such as 2020-6-21, 2020-6-22 etc ..) plus the number of users who have had 1 transaction in that date (day).
Any idea how can I do that?
EDIT: The result of query above is correct, the issue is, it's manually now. I mean, I have to increase 2020-6-21 by hand. I want to make it automatically. In other words, I want a list of all dates (from 2020-6-21 til now) contains the number of users who have had 1 transaction until that date.
If you want the number of users who had one transaction on each day, then you need to aggregate by the date as well:
select dte, count(*)
from (select date(created_at) as dte, user_id
from pos_transactions pt
where date(created_at) <= '2020-6-21'
group by dte, user_id
having count(*) = 1
) du
group by dte;

SQL query to find the cancellation rate of requests made between two dates using WITH

I'm trying to understand the right way to divide the count sums from two queries.
I'm teaching myself sql and practising it on line.
Question:
Write a SQL query to find the cancellation rate of requests made between 2017-08-01 and 2017-08-03. The cancellation rate is given by dividing the number of cancelled requests by the total number of rides each day. The result table should have 2 Columns, namely Day that shows each day and Cancellation Rate that provides the cancellation rate of that day.
Table is:
What I tried was:
count cancelled ride rates per date
count all ride requests per date
divide both the counts per date
with
cancelled_rides as
(select count(*) cancel_count, status, Request_id
from TRIPS
where status = 'cncld_driver'
group by state, Request_id)
all_rides as (
select count(*) day_count, status, Request_id
from TRIPS
group by state, Request_id) ,
select cancelled_rides.Request_id as DAY,
(cancelled_rides.cancel_count/all_rides.day_count) as 'Cancellation Rate'
FROM cancelled_rides, all_rides;
Does this look right? Note I purposefully ignored including date ranges as the table has only limited entries.
I do not see that a CTE helps at all for this query. Just use conditional aggregation:
select t.Request_id as day, count(*) as total,
sum( status = 'cncld_driver' ) as num_cancelled,
avg( status = 'cncld_driver' ) as cancellation_rate
from trips t
where request_id >= '2017-08-01' and
request_id < '2017-08-04'
group by request_id;
Calling a date "request_id" is rather confusing. You should have a request id that is unique for each row and a separate column with the date/time.

How to count total row on MySQL based upon month and year

My database table contains value in this way
IMAGE FOR TABLE DATA
I want to track down same email which has been used more than one times for a particular month and year.
In the above scenario, email that has been repeated multiple times was sandeshphuya#gmail.com, jes#gmail.com and ramu#gmail.com for different months. I want to track down customer repetition following their email for each month and year.
The query that I am using right now is
SELECT DATE_FORMAT(booked_on, '%Y-%m') as monthYear, email,
COUNT(*) AS 'Count'
FROM 'tablename'
GROUP BY email,DATE_FORMAT(booked_on, '%Y-%m') HAVING COUNT(*) > 1 ORDER BY `booked_on`;
GROUP BY email was used as it generates the repeated email and GROUP BY DATE_FORMAT(booked_on, '%Y'-%m') was used to track down total email repeated for each month/year.
This prints out data as
IMAGE FOR SELECT QUERY
How can I track down total repeated email following month and year? The expected result is
RESULT EXPECTED
You can use your query as a subquery for a new group by:
select sub.monthYear,count(*)
from
(SELECT DATE_FORMAT(booked_on, '%Y-%m') as monthYear,
email,
COUNT(*) AS 'Count'
FROM 'tablename'
GROUP BY email,DATE_FORMAT(booked_on, '%Y-%m')
HAVING COUNT(*) > 1
ORDER BY `booked_on`) as sub
GROUP BY sub.monthYear

related to query using SQL

In oracle sql, how to get the count of newly added customers only for the month of april and may and make sure they werent there in the previous months
SELECT CUSTOMER ID , COUNT(*)
FROM TABLE
WHERE DATE BETWEEN '1-APR-2018' AND '31-MAY-2018' AND ...
If we give max (date) and min(date), we can compare the greater date to check if this customer is new , correct?
expected output is month count
april ---
may ---
should show the exact count how many new customers joined in these two months
One approach is to use aggregation:
select customer_id, min(date) as min_date
from t
group by customer_id
having min(date) >= date '2018-04-01 and
min(date) < date '2018-06-01';
This gets the list of customers (which your query seems to be doing). To get the count, just use count(*) and make this a subquery.

Select all rows with the same aggregated value

There is a task: develop a fragment of the Web site that provides work with one table.
Attributes of the table:
Day of the week,
Time of the beginning of the lesson,
Subject name,
Number of the audience,
Full name of the teacher.
We need to make a query: determine the day of the week with the largest number of entries, if there are more than one maximum (ie, they are the same), then output them all. I did the query as follows:
SELECT COUNT (*) cnt, day
FROM schedule
GROUP BY day
ORDER BY cnt DESC
LIMIT 1;
But if there are several identical maxima, then only one is displayed. How to write a query which returns them all?
You can use your query as a subquery in the HAVING clause, e.g.:
SELECT day, count(*) as cnt
FROM schedule
GROUP BY day
HAVING count(*) = (
SELECT count(*) as cnt
FROM schedule
GROUP BY day
ORDER BY cnt DESC
LIMIT 1
)
ORDER BY day