sql table: sum up over intervals of 10 seconds - mysql

I'm looking for a solution for my statistical problem:
I have a table with one date column in it. Now what I want to do is count the number of rows in a certain time interval of 10 seconds:
SELECT count(id), ... AS interval WHERE ... GROUP BY interval
Anybody an idea how I can perform this?
Thanks,
Markus

SELECT
CONCATENATE(
SUBSTR(
DATE_FORMAT(yourtimestamp, '%Y%m%d%H%i%s')
, 1, -1)
, 0) AS time_bin,
COUNT(*)
FROM yourtable
WHERE ...
GROUP BY CONCATENATE(
SUBSTR(
DATE_FORMAT(yourtimestamp, '%Y%m%d%H%i%s')
, 1, -1)
, 0)
(use str_to_date() to convert back to a timestamp)
or...
SELECT FROM_UNIXTIME(
10*FLOOR(UNIX_TIMESTAMP(yourtimestamp)/10)
) AS time_bin,
COUNT(*)
FROM yourtable
WHERE ...
GROUP BY FROM_UNIXTIME(
10*FLOOR(UNIX_TIMESTAMP(yourtimestamp)/10)
)

Related

Group a sequence of lines [SQL]

Is there a way to group a sequence of rows in SQL (MySQL 5.1.73).
Let me explain, I have a query that gives this:
hour
start_date
end_date
10
2022-02-01 10:11:18
2022-02-01 10:50:18
11
2022-02-01 11:30:31
2022-02-01 11:38:12
13
2022-02-17 13:55:09
2022-02-17 13:58:38
14
2022-02-17 14:51:09
2022-02-17 14:57:59
And I would like to convert it to this:
hour
start_date
end_date
10
2022-02-01 10:11:18
2022-02-01 11:38:12
13
2022-02-17 13:55:09
2022-02-17 14:57:59
Indeed, I would like to group all the lines whose hours follow each other.
My request is a grouping in hours, like this :
SELECT hour( date ) as hour, MIN(date) as start_date , MAX(date) as end_date
FROM test_tbl
GROUP BY hour( date ) , date( date )
order by date, hour( date ) ;
But after doing this query, I would like to group the lines whose hours follow each other (10,11 => 10)...
EDIT: the following answer only works with MySQL version 8+
with tbl_by_hour as (
SELECT hour( date ) as hour, MIN(date) as start_date , MAX(date) as end_date
FROM test_tbl
GROUP BY hour( date ) , date( date )
order by date, hour( date )
)
select
min(hour) as hour,
min(start_date) as start_date,
max(end_date) as end_date
from (
select tab1.*,
sum(case when prev_hour is null or prev_hour = hour - 1 then 0 else 1 end) over(order by hour) grp
from (
select hour, start_date, end_date, lag(hour) over(order by hour) prev_hour from tbl_by_hour
) as tab1
) as tab2
group by grp
You can probably do something like this:
SELECT MIN(hours), dates, MIN(start_date), MAX(end_date), tn
FROM
(SELECT *,
CEIL(rownum/5) AS tn
FROM
(SELECT *,
CASE WHEN dates=#dt
AND hours=#hr+1
THEN #rn := #rn+1
WHEN dates=#dt
AND hours > #hr+1
THEN #rn := #rn+20
ELSE #rn := 1
END AS rownum,
#dt := dates,
#hr := hours
FROM
(SELECT hour(date) as hours, date(date) dates,
MIN(date) as start_date , MAX(date) as end_date
FROM test_tbl t
GROUP BY dates, hours) v
CROSS JOIN (SELECT #rn := 0, #dt := NULL, #hr := 0) r
ORDER BY dates, hours) s
) w
GROUP BY dates, tn;
I took your original query as base then made it as subquery.
Then I CROSS JOIN with a subquery of variables where I'm attempting to generate a custom row numbering. The conditions of the row number are:
If it's on the same date and the next hour increment from previous is +1 then continue the numbering.
If it's on the same date and the next hour increment from previous more than +1 then pick-up the last number and increment it by +20.
Repeat the row numbering sequence if the date is different.
After generating the row numbering, I convert to subquery then divide the row numbering by 5 and use ceiling (CIEL) function to somehow make them the same, effectively identifying (assuming) these rows with same CIEL(rownum/5) result as one group - this is where I felt it's not really convincing but it works anyhow.
Lastly, I convert that to a subquery again and did the whole MIN(hours), dates, MIN(start_date), MAX(end_date), tn with GROUP BY dates, tn.
It's not a convincing solution because the final operation (generating of the tn column) is based on creativity and not something certain. I usually prefer a solution that covers all the possible scenarios with something concrete rather than creative. However, I did some extensive tests on the current query with more data variation and so far it's returning good results. Also, I do notice that you said your MySQL version is 5.1+ so, I'm not really sure if this particular operation will work. Version 5.5+ is probably the lowest version of MySQL fiddle that is available online.
Here's a demo fiddle

I have a query written in Oracle , would like to convert into MySQL

select * from
(
select week_of, COUNT(DISTINCT CUSTOMER_ID) AS weekly_developer_count, COUNT(DISTINCT APPLICATION_ID) as weekly_app_count from
(
select PE.EVENT_DAY_UTC, to_char(next_day(PE.EVENT_DAY_UTC - 1, 'SUNDAY'), 'YYYY-MM-DD') as week_of, PE.CUSTOMER_ID, PE.APPLICATION_ID
from tablename PE
where
PE.EVENT_DAY_UTC >= SYSDATE - 90
and PE.EVENT_DAY_UTC < SYSDATE + 1
and PE.EVENT_NAME NOT LIKE '%.%'
)
group by week_of
)
order by week_of desc;
This is the code I have it in Oracle, MySQL doesn't support NEXT_DAY. Any idea to achieve this?
I want as the output something like
Weekof ApplicationCount DeveloperCount
2016-17-07 50 10
2016-10-07 60 15
You can implement your own function, like described here:
MySQL implementation of Oracle's next_day
You can probably replace next_day with an appropriate combination of date math and DAYOFWEEK, something like:
mydate + INTERVAL (8-DAYOFWEEK(mydate)) DAY
should work for Sunday
Here's a MySQL stored function you can define that does the same thing as Oracle's NEXT_DAY():
CREATE FUNCTION next_day (date DATE, dow VARCHAR(10)) RETURNS DATE
RETURN FROM_DAYS(
TO_DAYS(date) - DAYOFWEEK(date)
+ IF(DAYOFWEEK(date) >= FIND_IN_SET(dow, 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday'), 7, 0)
+ FIND_IN_SET(dow, 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday')
);

Why am i getting this error message ( #1111 - Invalid use of group function )?

I am trying to retrieve the TIMEDIFF from the last_call field of every row, where TIMEDIFF between current row and next row is greather than 10 min!
Can someone please help? Meybe there is a better way of doing this?
My goal is to get the total of all timediff between severall database entrys but only if they are greather than 10 min.
SELECT DATE_FORMAT( last_call, '%d' ) AS 'day',
(
SELECT TIME_TO_SEC(TIMEDIFF(MAX(cl1.last_call), MIN(cl1.last_call)))
FROM calls AS cl1
WHERE TIME_TO_SEC(TIMEDIFF(MAX(cl1.last_call), MIN(cl1.last_call))) > 600
AND cl1.calling_agent=9
AND EXTRACT(DAY FROM cl1.last_call ) = EXTRACT(DAY FROM calls.last_call )
) AS 'brake'
FROM calls
WHERE calling_agent =9
AND last_call > DATE_SUB( now( ) , INTERVAL 12 MONTH )
GROUP BY EXTRACT( DAY FROM last_call )

MYSQL group by day, week and month with php timestamp [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
MySQL Query GROUP BY day / month / year
I have php timestamps (e.g. 1307362819) stored in a column in my database. I want to group count(*) in days, weeks and months the data.
For example I want to find out how many entries there are per day, per week, and per month etc.
How can this be achieved?
You can subtract day, week and month value from a timestamp, and group the subtracted values.
grouping by day value:
select count(*) from table group by from_unixtime(timeStampColumn, '%Y%m%d')
grouping by week value:
select count(*) from table group by from_unixtime(timeStampColumn, '%Y%m%u')
grouping by monthvalue:
select count(*) from table group by from_unixtime(timeStampColumn, '%Y%m')
For more information, have a look at this page: http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html
Why don't you use these: <>
SELECT COUNT(*) FROM yourTable WHERE yourTimestampField > someTimestampAWeekPast;
SELECT COUNT(*) FROM yourTable WHERE yourTimestampField > someTimestampADayPast;
Use the mysql date/time functions http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html to calculate the desired date in the past.
Use UNIX_TIMESTAMP if you stored them as int or string or whatever.
here a good exemple for you
to group by week
EDIT:
try this
select
id_user,
year(time) as AYear, week(time) as AWeek, day(time) as Aday ,
count(week(time)) as TotalPerWeek , count(day(time)) as TotalPerDay ,
count(year(time)) as TotalPerYear
from yourtable
where id_user = 16 //// the user u want to check
group by id_user, AYear, AWeek , Aday
order by AYear, AWeek , Aday
SELECT MONTH( FROM_UNIXTIME( `timeStamp` ) ) , COUNT( `id` )
FROM `discusComments`
GROUP BY MONTH( FROM_UNIXTIME( `timeStamp` ) )

Trying to embed date_add comparison in MySQL query

Should be fairly self-explanatory; any idea why I can't do:
select user_id from my_table where created_at<date_add(min(created_at), INTERVAL 1 MINUTE)
I'm trying to only return rows that have been created within a minute of the earliest timestamp. Thanks!
You should use HAVING instead of WHERE when dealing with aggregate functions... Still, your query will be a bit more complex, I guess:
SELECT user_id,
created_at, (
SELECT DATE_ADD(MIN(created_at), INTERVAL 1 MINUTE)
FROM my_table
) AS earliest
FROM my_table t1
HAVING created_at < earliest;
Here's a SQLFiddle to play with. )
Try this:
SELECT user_id
FROM my_table
WHERE created_at < DATE_ADD((SELECT MIN(created_at) FROM my_table), INTERVAL 1 MINUTE)
SELECT user_id FROM my_table
WHERE created_id <
(
SELECT (min_dt + INTERVAL 1 MINUTE) mindt FROM
(SELECT MIN(created_id) min_dt FROM my_table) A
);