Group results by period - mysql

I have some data which I want to retrieve, but I want to have it grouped by a specific number of seconds. For example if my table looks like this:
| id | user | pass | created |
The created column is INT and holds a timestamp (number of seconds from 1970).
I would want the number of users that are created between last month and the current date, but show them grouped by let's say 7*24*3600 (a week). So if in the range there are 1000 new users, have them show up how many registered each week (100 the first week, 450 the second, 50 the third and 400 the 4th week -- something like this).
I've tried grouping the results by created / 7*24*3600, but that's not working.
How should my query look like?

You need to use integer division div otherwise the result will turn into a real and none of the weeks will resolve to the same value.
SELECT
(created div (7*24*60*60)) as weeknumber
, count(*) as NewUserCount
FROM users
WHERE weeknumber > 1
GROUP BY weeknumber
See: http://dev.mysql.com/doc/refman/5.0/en/arithmetic-functions.html

You've got to keep the integer part only of that division. You can do it with the floor() function.
Have you tried select floor(created/604800) as week_no, count(*) from users group by floor(created/604800) ?
I assume you've got the "select users created in the last month" part sorted out.

Okay here are the possible options you may try:
GROUP BY DAY
select count(*), DATE_FORMAT(created_at,"%Y-%m-%d") as created_day FROM widgets GROUP BY created_day
GROUP BY MONTH
select count(*), DATE_FORMAT(created_at,"%Y-%m") as created_month FROM widgets GROUP BY created_month
GROUP BY YEAR
select count(*), DATE_FORMAT(created_at,"%Y") as created_year FROM widgets GROUP BY created_year

Related

Get amount of active user of the last n days grouped by date

Suppose I have a Hive table logins with the following columns:
user_id | login_timestamp
I'm now interested in getting some activity KPIs. For instance, daily active user:
SELECT
to_date(login_timestamp) as date,
COUNT(DISTINCT user_id) daily_active_user
FROM
logins
GROUP BY to_date(login_timestamp)
ORDER BY date asc
Changing it from daily active to weekly/monthly active is not a great deal because I can just exchange the to_date() function to get the month and then group by that value.
What I now want to get is the distinct amount of user who were active in the last n days (e.g. 3) grouped by date. Additionally, what I'm looking for is a solution that works for a variable time window and not only for one day (getting the amount of active user of the last 3 days on day x only would be easy).
The result is supposed to like somewhat like this:
date, 3d_active_user
2017-12-01, 111
2017-12-02, 234
2017-12-03, 254
2017-12-04, 100
2017-12-05, 103
2017-12-06, 103
2017-12-07, 230
Using a subquery in the first select (e.g. select x, (select max(x) from x) as y from z) building a workaround for the moving time window is not possible because it is not supported by the Hive version I'm using.
I tried my luck something like COUNT(DISTINCT IF(DATEDIFF(today,login_date)<=3,user_id,null)) but everything I tried so far is not working.
Do you have any idea on how to solve this issue?
Any help appreciated!
You can user "BETWEEN" function.
If you want to find the active users, log in from the particular date to till now.
SELECT to_date(login_timestamp) as date,COUNT(DISTINCT user_id) daily_active_user
FROM logins
WHERE login_timestamp BETWEEN startDate_timeStamp AND now()
GROUP BY to_date(login_timestamp)
ORDER BY date asc
If you want the active users, who are log in users for specific date range then:
NOTE:-
SELECT to_date(login_timestamp) as date,COUNT(DISTINCT user_id) daily_active_user
FROM logins
WHERE login_timestamp BETWEEN to_date(startDate_timeStamp) AND to_date(endDate_timeStamp)
GROUP BY to_date(login_timestamp)
ORDER BY date asc

how can I calculate the SUM in 4days buckets over all dates

I have a MySQL DB where one column is the DATE and the other column is the SIGNAL. Now I would like to calculate the SUM over Signal for 4 days each.
f.e.
SUM(signal over DATE1,DATE2,DATE3,DATE4)
SUM(signal over DATE5,DATE6,DATE7,DATE8)
...
whereas Date_N = successor of DATE_N-1 but need not to be the day before
Moreless the algo should be variable in the days group. 4 ist just an example.
Can anyone here give me an advice how to perform this in MySQL?
I have found this here group by with count, maybe this could be helpful for my issue?
Thanks
Edit: One important note: My date ranges have gaps in it. you see this in the picture below, in the column count(DISTINCT(TradeDate)). It should be always 4 when I have no gaps. But I DO have gaps. But when I sort the date descending, I would like to group the dates together always 4 days, f.e. Group1: 2017-08-22 + 2017-08-21 + 2017-08-20 + 2017-08-19, Group2: 2017-08-18 + 2017-08-17+2017-08-15+2017-08-14, ...
maybe I could map the decending dateranges into a decending integer autoincrement number, then I would have a number without gaps. number1="2017-08-17" number2="2017-08-15" and so on ..
Edit2:
As I see the result from my table with this Query: I might I have double entries for one and the same date. How Can I distinct this date-doubles into only one reprensentative?
SELECT SUM(CondN1),count(id),count(DISTINCT(TradeDate)),min(TradeDate),max(TradeDate) ,min(TO_DAYS(DATE(TradeDate))),id FROM marketstat where Stockplace like '%' GROUP BY TO_DAYS(DATE(TradeDate)) DIV 4 order by TO_DAYS(DATE(TradeDate))
SUM() is a grouping function, so you need to GROUP BY something. That something should change only every four days. Let's start by grouping by one day:
SELECT SUM(signal)
FROM tableName
GROUP BY date
date should really be of type DATE, like you mentioned, not DATETIME or anything else. You could use DATE(date) to convert other date types to dates. Now we need to group by four dates:
SELECT SUM(signal)
FROM tableName
GROUP BY TO_DAYS(date) DIV 4
Note that this will create an arbitary group of four days, if you want control over that you can add a term like this:
SELECT SUM(signal)
FROM tableName
GROUP BY (TO_DAYS(date)+2) DIV 4
In the meantime and with help of KIKO I have found the solution:
I make a temp table with
CREATE TEMPORARY TABLE if not EXISTS tradedatemaptmp (id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY) SELECT Tradedate AS Tradedate, CondN1, CondN2 FROM marketstat WHERE marketstat.Stockplace like 'US' GROUP BY TradeDate ORDER BY TradeDate asc;
and use instead the originate tradedate the now created id in the temp table. So I could manage that - even when I have gaps in the tradedate range, the id in the tmp table has no gaps. And with this I can DIV 4 and get the always the corresponding 4 dates together.

Get the max value of different sum values in sql

I have a table called "Sold_tickets" with attributes "Ticket_id" and "Date_sold". I want to find the day when the most tickets have been sold and the amount of tickets that were sold.
ticket_id date_sold
1 2017-02-15
2 2017-02-15
3 2017-02-14
In this case I want my output to look like this:
date_sold amount
2017-02-15 2
I know you can use a query like this
SELECT Count(ticket_id)
FROM Sold_tickets
WHERE date_sold = '2017-02-15';
to get an output of 2. The same can of course be done for 2017-02-14 to get an output of 1. However, then I have to manually check all the dates and compare them myself. Does a function exist (in sqlite) that counts the tickets sold for all the dates and then shows you only the maximum value?
Try using a GROUP BY aggregation query, then retain only the record having the maximum number of sales.
SELECT date_sold, COUNT(*)
FROM Sold_tickets
GROUP BY date_sold
ORDER BY COUNT(*) DESC
LIMIT 1
This solution would work well assuming that you don't have two or more dates tied for the greatest number of sales, or, if there is a tie, that you don't mind choosing just one date group.

How to get the average price for the X most recent rows based on date?

I am looking to calculate moving averages over variable dates.
My database is structured:
id int
date date
price decimal
For example, I'd like to find out if the average price going back 19 days ever gets greater than the average price going back 40 days within the past 5 days. Each of those time periods is variable.
What I am getting stuck on is selecting a specific number of rows for subquery.
Select * from table
order by date
LIMIT 0 , 19
Knowing that there will only be 1 input per day, can I use the above as a subquery? After that the problem seems trivial....
if you only have one input per day you don't need id, date can be your primary id? Am i missing something? Then use select sum
SELECT SUM(price) AS totalPrice FROM table Order by date desc Limit (most recent date),(furthest back date)
totalPrice/(total days)
I may not understand your question
Yes you can use that as a sub-query like this:
SELECT
AVG(price)
FROM
(SELECT * FROM t ORDER BY date DESC LIMIT 10) AS t1;
This calculates the average price for the latest 10 rows.
see fiddle.

Number of Posts as per days in a month

There is a table Post in my database which contains posts of different users. What I wanna do is to create an sql query that'll return as per respective month the number of posts being made each day. Kindly let me know how can i do that generically in one query i can create multiple queries for all days but that is a worst case scenario. So I need expert's solution to this.
Thanks
Expected output:
(Query counts the number of posts for all the days in a respective month)
Day : Number of posts
1 : 20
2 : 25
3 : 10
4 : 17
.........................
30 : 6
Table Structure:
ID | postid | post | date
select DAYOFMONTH(date) as Day , count(*) as Number_of_posts
from table
group by DAYOFMONTH(date)
You should know that if table contains data from different months number of posts will be wrong.
So the group by should be by date and you should use date in selected instead of day of month.
SELECT DAYOFMONTH(date), count(*) FROM Post
GROUP BY DAYOFMONTH(date)
ORDER BY DAYOFMONTH(date) ASC;
If you want to query for a specific month (say, February) then use this:
SELECT DAYOFMONTH(date), count(*) FROM Post
WHERE MONTH(date) = '2'
GROUP BY DAYOFMONTH(date)
ORDER BY DAYOFMONTH(date) ASC;
Note: Months are returned in number form where the MONTH() function is used.
EDIT: If you're looking to return counts for EVERY day in a given month, then I'd push you here - a great accepted answer to a similar question: How to get values for every day in a month
SELECT date, COUNT(id) as number_of_posts FROM table_name GROUP BY date.