Calculate average session length per daily active user? - mysql

I'm pretty new to SQL and I'm struggling with one of the questions on my exercise. How would I calculate average session length per daily active user? The table shown is just a sample of what the extended table is. Imagine loads more rows.
I simply used this query to calculate the daily active users:
SELECT COUNT (DISTINCT user_id)
FROM table1

and welcome to StackOverflow!
now, your question:
How would I calculate average session length per daily active user?
you already have the session time, and using AVG function you will get a simple average for all
select AVG(session_length_seconds) avg from table_1
but you want per day... so you need to think as group by day, so how do you get the day? you have a activity_date as a Date entry, it's easy to extract day, month and year from it, for example
select
DAY(activity_date) day,
MONTH((activity_date) month,
YEAR(activity_date) year
from
table_1
will break down the date field in columns you can use...
now, back to your question, it states daily active user, but all you have is sessions, a user could have multiple sessions, so I have no idea, from the context you have shared, how you go about that, and make the avg for each session, makes no sense as data to retrieve, I'll just assume, and serves this answer just to get you started, that you want the avg per day only
knowing how to get the average, let's create a query that has it all together:
select
DAY(activity_date) day,
MONTH((activity_date) month,
YEAR(activity_date) year,
AVG(session_length_seconds) avg
from
table_1
group by
DAY(activity_date),
MONTH((activity_date),
YEAR(activity_date)
will output the average of session_length_seconds per day/month/year
the group by part, you need to have as many fields you have in the select but that do not do any calculation, like sum, count, etc... in our case avg does calculation, so we don't want to group by that value, but we do want to group by the other 3 values, so we have a 3 columns with day, month and year. You can also use concat to join day, month and year into just one string if you prefer...

Related

MySQL average two level agregation

Suppose I have a table with four fields in MySQL (id, week, day, value). The id field is an identifier for a device that takes several values per day.
What I want is calculate an average of value in a week-daily basis. The result will be other table with three fields (id, week, average_week_day_value), where the average value is not the average in a week basis, but in a week-daily basis. I mean: first we calculate the day-average, and after that, the week-day-average as an average of days-average-values per week.
Now, I implement that in two steps, with an intermediate table (id, week, day, average-day-value). After I have the intermediate table it's easy to calculate final table: (id, week, average_week_day_value)
Can I do that in a single step?
EDIT
First step query:
INSERT INTO daily (id,week,day,average)
SELECT id, week, day, avg(value)
FROM table_values
GROUP BY day
Second step query:
INSERT INTO weekly (id,week,avg)
SELECT id,week,avg(average)
FROM daily
GROUP BY week
You can just put your first query in a subquery.
SELECT week, AVG(day_avg)
FROM (
SELECT week, day, AVG(value) AS day_avg
FROM table_values
GROUP BY week, day
) d
GROUP BY week

Am I calculating average income per hour by day of week correctly?

data table looks like this
Use a query to calculate average income per hour by day of week.
SELECT WEEKDAY(date_start_time), SUM(total_income)/SUM(DATEDIFF((hour,
date_start_time, date_end_time) AS avg_income
FROM Deliveries
GROUP BY WEEKDAY(date_start_time)
Things to know:
Entry_id is a unique key for each time the employee comes into the office
There will be many records of the same user_id if an employee comes into the office repeatedly
Tasks completed will most likely stay unused in this question
Am I appropriately answering this question?
Things I am concerned about:
1) Does DATEDIFF only return an integer value? If thats the case, then to have a better estimation of the avg_income does this mean we should use DATEDIFF(minutes, ..., ...) and then calculate the hours with decimal places from that integer?
2) Are people working overnight shifts something that I need to worry about? How much more complicated would it make this query?
3) Moving onward if I was asked to "calculate the average earnings per hour during 9am to 5pm" does this mean I need to calculate this for each individual employee... or for each individual hour (ie. ultimately am I grouping by hour or by user_ID)?
1) Use timediff()
2) You will not only need to consider overnight shifts but you will need to consider overtime pay if they work > 40 hours in between the week start date and the week end date for a given week. This is only if employees are paid different hourly rates for these (ex.time and a half). If this is a factor then you will need to roll up your sleeves because it will be a full algorithm.
3) This depends on what you are trying to find the average by (user, day, etc.) but a simple way would be to just nest your select and grab an avg().
select avg(earnings) overall_average from
(select user, [calculated_earnings] as earnings from [table] where [conditions])
select avg(earnings) overall_average from
(select weekday, [calculated_earnings] as earnings from [table] where [conditions])

MySQL: Select count of returning vs. new rows in MySQL with period

I have database table in MySQL, which consist of the following fields:
id
user_id
timestamp
The table is a simple log of visitors. I am trying to get the following numbers in one query:
Distinct user_id's for a specific time period (30 days)
Amount of these user_id's, which already exist in the table, regardless of time period
I have been able to do it within the period with this simple query:
SELECT
COUNT(DISTINCT user_id) AS 'count_distinct',
COUNT(user_id) AS 'count_all'
FROM
table
WHERE
timestamp BETWEEN CURDATE() - INTERVAL 30 DAY AND CURDATE();
Running this query gives me the count of distinct user_id's and the count of all user_id's within the time period. I can then apply the math myself to get the count of new vs. returning visitors - for that period. What I am trying to figure out is how many distinct user_id's, who visited within 30 days, who has also visited at any previous point in time.
I hope you can help me solve this.

SQL Statement to get daily totals

I'm storing some data in a table and I want to be able to display the total data points per day on the graph. So the first graph point might be 7 for Monday, Jan 1, 2013, and then 3 for Tuesday, Jan 2, 2013...etc.
I have full time/date stamps for each of my data points in my table of SQL type datetime.
My pseudo statement looks like this, but I'm concerned since I'm using the datetime data type:
SELECT
DATE(created_at) AS create_date
COUNT(id) AS total
FROM
data_table
GROUP BY
create_date
How can I get the total data points per day, regardless of the timestamp?
Try this
SELECT
DATE(created_at) AS create_date,
COUNT(id) AS total
FROM
data_table
GROUP BY
DATE(created_at)
Best would be to start a daily cron job that stores the number of the data points for every day. So you can every day count the number between let's say 24.00.00 to 23.59.59.
If you want to count them on the fly you might have slow requests on huge data amounts, since the grouping query cannot use table index.
But maybe you can add a new table column where you store just the date additionally to the timestamp.

Getting the average number of orders per day using mysql

I have the following table structure:
ID, User_ID, DateTime
Which stores a user id and datetime of an order purchased. How would I get the average number of orders a day, across every row?
In pseudo code I'm thinking:
Get total number of orders
Get number of days in range (from first row to last row).
Divide 1. by 2. to get average?
So it would return me a value of 50, or 100?
Thanks
Since you know the date range, and you are not guaranteed to have and order on these dates, you can't just subtract the max(date) from min(date), but you know the number of days before you run the query, therefore simply:
select count(*) / <days>
from mytable
where DateTime between <start> and <end>
Where you supply the indicated values because you know them.
select DATEDIFF(NOW(), date_time) as days, AVG(count(*))
from table
group by days
I have not tested the query, its just the idea, I guess it should work.