Get Daily Active Users for the last 2 weeks - mysql

I have a log on our app that logs all user activity along with a unix timestamp and I now want to create a function that will return the data needed to display the number of DAU each day in the last 2 weeks. Ive googled around a bit , but I have been unable to find a straightforward question on Stack regarding how to even start to go about such a query . Maybe my querying knowledge just is not advanced enough , excuse my ignorance if this is the case. I just have no idea how to group individual dates + unique user totals in a single query.
my table is setup as following
|LOG_ID | TYPE_OF_REQUEST | USER_ID | TSTAMP |

You can start by filtering
WHERE TSTAMP <= DATE_SUB(NOW(), INTERVAL 2 WEEK))
To filter only the two last weeks
And then
GROUP BY USER_ID
Perhaps combining a COUNT(TYPE_OF_REQUEST)
Depends on what info you are trying to achieve

Related

Query with three tables, no common column

I've just started a job and my boss wants me to learn mySQL so please bear with me, i've been learning for only 2 days and i'm not that good at it yet.
So i've been given 3 tables and several tasks to do.
The tables are:
mobile_log_messages_sms
mobile_providers
service_instances
And in them i've got to:
Find out how many messages there were in the last 25 days and how
much income did they make
Then i need to group them by day (so per day, exclude hours) and
provider name.
Also i need to ignore all the messages that have an empty string
under the service column
Also i need to ignore the messages that made 0 income and count only
those that have the column service_enabled = 1
And then i need to sort it descending, by date.
in the tables
mobile_log_messages_sms:
message_id - used to count the messages
price - using for price obviously, exlude those with 0
time - date in yyyy/mm/dd hh:mm:ss format
service - exclude all those that have an empty string (or null)
mobile_providers
provider_name - to use to group with
service_instances
enabled - only use if value is 1
I've started with:
SELECT message_id, price, time
FROM mobile_log_messages_sms
WHERE time BETWEEN '2017-02-26 00:00:00'
AND time AND '2017-03-22 00:00:00'
But i need to change the date format and then use the JOIN commands but i don't know how, and i know i need to add more to it, but i'm stumped even at the start. Also the starting just lists the messages but i need to count the total sum of the income (price) per day.
Can anyone point me in the right direction at least since i'm still a noob? Many thanks in advance and sorry if i worded something badly, english is not my first language.
Find out how many messages there were in the last 25 days and how much income did they make
1.
SELECT COUNT(message_id), SUM(price)
FROM mobile_log_messages_sms
WHERE CAST(time AS DATE) BETWEEN DATE_SUB(CURRENT_DATE,INTERVAL 25 DAY)
AND CURRENT_DATE;
2.
SELECT COUNT(message_id), SUM(price)
FROM mobile_log_messages_sms
WHERE CAST(time AS DATE) BETWEEN DATE_SUB(CURRENT_DATE,INTERVAL 25 DAY)
AND CURRENT_DATE
GROUP BY CAST(time AS DATE);
3.
SELECT COUNT(message_id), SUM(price)
FROM mobile_log_messages_sms
WHERE CAST(time AS DATE) BETWEEN DATE_SUB(CURRENT_DATE,INTERVAL 25 DAY)
AND CURRENT_DATE AND service IS NULL
GROUP BY CAST(time AS DATE);
rest can't done with join so make sure that at least one column should be common in tables.

Need better database design approach

I have designed a database schema for a subscription product. user can select subscription starting from a date for certain amount of days. User can cancel a subscription for some days while still keeping the subscription active afterwards. meaning if user subscribes for a month she can cancel it on days say 10,15 and 20 thus paying for only 27 days (30 minus 3).
So far I have come up with this schema.
each user has one profile.
user can select a plan.
once user selects a plan it is noted as transaction which also stores information about start date and duration of that plan.
each transaction has payment (focusing on that part later)
Now, since user can cancel subscription any day how should I keep track of different users and days on which they had subscription?
The solution that I have in mind is crate a new table Plan_Transaction_user which will keep track of each date and transaction ID for that date. This way If user cancels her subscription on particular date there will be no record of that date for that transaction ID.
table will look like this:
Date Transaction ID
1-1-2017 1
1-1-2017 2
1-1-2017 3
1-2-2017 1
1-2-2017 3
Since user associated with transaction_id 2 cancelled for day 2 her transaction record is not present in this table.
Now if I have customer base of say 5000 then in best case within one year I will have 5000 * 365 ~ 1.8m rows. I am sure this is not best approach to go about it. Could you please suggest me any better schema or some changes in existing schema which can be more efficient? Just in case you want to know I will be using MariaDB (AWS RDS) as a database and Python 2 as my language.
Thank you,
Ojas
You can add a end_date field in Transaction table instead of duration. You can easily defined end_date as start_date + how many days you will given for selected plan. When user cancel some days then you can reduce end_date as end_date = end_date - number of cancel days. You can check how many valid subscription currently at any days checking through end_date >= today.
Similar to your Plan_Transaction_user design, if u only need to know how many subscribers for any particular date, but not who they are, u can aggregate the table by day. Like
Date user_count
1-1-2017 1
1-2-2017 2

Date Difference in MySql via Codeigniter

I'm a little lost on how I should do this any help or guidance would be appreciated. I have a table that has 3 columns with multiple values inserted into it basically a log_book table of events. We can say there is an order_id, event_status, and datetime. I need to get the difference of days between the datetime columns and sum them together where order_id=? and event_status=? I know how to limit my queries to get the data I want. But what would be the best way to get the difference in days and add them together. Essentially there could be only one entry with the same order_id and event_status or there could be multiple entries with the same order_id and event_status.
Event Status codes
1 = initially assigned
2 = submitted for review
3 = sent back for more work
because 2015-01-01 to 2015-01-15 is 15 days
and 2015-01-17 to 2015-01-18 is 1 day
so the total days would be: 16 Days

Grouping by time ignoring the Date portion

I have a table that has a column that is called scores and another one that is called date_time
I am trying to find out for each 5 minute time increment how many I have that are above a certain score. I want to ignore the date portion completely and just base this off of time.
This is kind of like in a stats program where they display your peak hours with the only difference that I want to go is detailed as 5 minute time segments.
I am still fairly new at MySQL and Google seems to be my best companion.
What I have found so far is:
SELECT id, score, date_time, COUNT(id)
FROM data
WHERE score >= 500
GROUP BY TIME(date_time) DIV 300;
Would this work or is there a better way to do this.
I don't think your query would work. You need to do a bit more work to get the time rounded to 5 minute intervals. Something like:
SELECT SEC_TO_TIME(FLOOR(TIME_TO_SEC(time(date_time))/300)*300) as time5, COUNT(id)
FROM data
WHERE score >= 500
GROUP BY SEC_TO_TIME(FLOOR(TIME_TO_SEC(time(date_time))/300)*300)
ORDER BY time5;

How to get the previous 6 weeks result for this week in mysql

I can get the total entries for each week with the code below.
select week(date_created) as week, count(distinct tag_code) as Total_This_Week
from entries
where date_created between '2000-01-01' and '2020-01-01'
group by week;
But what I need to get is the total_last_6_weeks column like below which is the previous 6 weeks added up so for week 6 the total_Last_6_weeks is '370' is gotten by adding up (56+45+85+34+85+65). And this must happen every week so for week 9 it must add up the previous 6 weeks. Everything I've tried does not seem to work.
+-----+-----------------+--------------------+
| week| Total_This_Week | total_Last_6_Weeks |
+-----+-----------------+--------------------+
|__0__|_______81________|_______ 122________ |
|__1__|_______65________|________188________ |
|__2__|_______85________|________145_________|
|__3__|_______34________|________205_________|
|__4__|_______85________|________189_________|
|__5__|_______45________|________112_________|
|__6__|_______56________|________370_________|
|__7__|_______32________|________518_________|
|__8__|_______34________|________121_________|
|__9__|_______45________|________224_________|
+-----+-----------------+--------------------+
In SQL Server or Oracle you could lag the date_created by six weeks and use
over (partition by ...)
to get the cumulative sums, while the difference would give you the sum for 6 weeks on a rolling basis.
I understand that in MySQL you can do this via using variables, as partition and over do not directly exist. Here is a brief summary of how to go about it:
ROW_NUMBER, Partition and Over in MySQL