SQL Query to check rate limit - mysql

Lets say I have a table of messages that users have sent, each with a timestamp.
I want to make a query that will tell me (historically) the most number of messages a user ever sent in an hour.
So in other words, in any given 1 hour period, what was the most number of messages sent.
Any ideas?

Assuming timestamp to be a DATETIME - otherwise, use FROM_UNIXTIME to convert to a DATETIME...
For a [rolling] count within the last hour:
SELECT COUNT(*) AS cnt
FROM MESSAGES m
WHERE m.timestamp BETWEEN DATE_SUB(NOW(), INTERVAL 1 HOUR)
AND NOW()
GROUP BY m.user
ORDER BY cnt DESC
LIMIT 1
If you want a specific hour, specify the hour:
SELECT COUNT(*) AS cnt
FROM MESSAGES m
WHERE m.timestamp BETWEEN '2011-06-06 14:00:00'
AND '2011-06-06 15:00:00'
GROUP BY m.user
ORDER BY cnt DESC
LIMIT 1

Need more details on table structure etc. but something like:
select date(timestmp), hour(timestmp) , count(*)
from yourtable group by date(timestmp) , hour(timestmp)
order by count(*) DESC
limit 100;
would give you hte desired result.

Something like this should work:
SELECT MAX(PerHr) FROM
(SELECT COUNT(*) AS PerHr FROM messages WHERE msg_uid=?
GROUP BY msg_time/3600) t

I suspect this would be horribly slow, but for an arbitrary historical max hour, something like this might work (downvote me if I'm way off, I'm not a MySQL person):
SELECT base.user, base.time, COUNT(later.time)
FROM messages base
INNER JOIN messages later ON later.time BETWEEN base.time AND DATE_ADD(base.time, INTERVAL 1 HOUR) AND base.user = later.user
WHERE base.user = --{This query will only work for one user}
GROUP BY base.user, base.time
ORDER BY COUNT(later.time) DESC
LIMIT 1

Related

Amount of Inserts per minute SQL

I have a table with a column called timestamp (YYYY-MM-DD HH:MM:SS) and message. How would I display how many messages where sent every minute (not just in an given time).
I've done this but it's for every time. How would I go about changing it
to count the number sent from HH-00:00 to HH:01:00 and so on.
SELECT timestamp, COUNT(*)
FROM Messages
GROUP BY timestamp
ORDER BY timestamp DESC
SELECT TIMESTAMP(DATE(timestamp),MAKETIME(HOUR(timestamp),MINUTE(timestamp),0))
,COUNT(1)
FROM
Messages
GROUP BY TIMESTAMP(DATE(timestamp),MAKETIME(HOUR(timestamp),MINUTE(timestamp),0))
ORDER BY TIMESTAMP(DATE(timestamp),MAKETIME(HOUR(timestamp),MINUTE(timestamp),0))
Try:
SELECT HOUR(timestamp) AS Hour,
MINUTE(timestamp) AS minute,
COUNT(*)
FROM Messages
GROUP BY HOUR(timestamp), MINUTE(timestamp)
ORDER BY HOUR(timestamp) DESC, MINUTE(timestamp) DESC

MySQL combine 2 different counts in one query

I have a table, that pretty much looks like this:
users (id INT, masterId INT, date DATETIME)
Every user has exactly one master. But masters can have n users.
Now I want to find out how many users each master has. I'm doing that this way:
SELECT `masterId`, COUNT(`id`) AS `total` FROM `users` GROUP BY `masterId` ORDER BY `total` DESC
But now I also want to know how many new users a master has since the last 14 days. I could do it with this query:
SELECT `masterId`, COUNT(`id`) AS `last14days` FROM `users` WHERE `date` > DATE_SUB(NOW(), INTERVAL 14 DAY) GROUP BY `masterId` ORDER BY `total` DESC
Now the question: Could I somehow get this information with one query, instead of using 2 queries?
You can use conditional aggregation to do this by only counting rows for with the condition is true. In standard SQL this would be done using a case expression inside the aggregate function:
SELECT
masterId,
COUNT(id) AS total,
SUM(CASE WHEN date > DATE_SUB(NOW(), INTERVAL 14 DAY) THEN 1 ELSE 0 END) AS last14days
FROM users
GROUP BY masterId
ORDER BY total DESC
Sample SQL Fiddle

Reverse order for GROUP BY in MySQL

I need to select first value for every hour from my db. But I don't know how to reverse order on GROUP BY statement.
How can i rewrite my query (now it selects last value in hour)?
SELECT HOUR(`time`) as hour, mytable.*
FROM mytable
WHERE DATE(`time`) ="2015-09-12" GROUP BY HOUR(`time`) ORDER BY `time` ASC;
This query gave me expected result:
SELECT HOUR(`time`) as hour, sortedTable.* FROM
(SELECT electrolysis.* FROM electrolysis
WHERE DATE(`time`)='2015-09-12' ORDER BY `time`) as sortedTable
GROUP BY HOUR(`time`);
You can just select the MIN HOUR in sub query , try using the query:
SELECT * from mytable WHERE `time` IN (
SELECT MIN(HOUR(`time`)) as `hour`
FROM mytable
WHERE DATE(`time`) ="2015-09-12"
GROUP BY HOUR(`time`) ) ORDER BY `time` ASC;
You can do something like this:-
SELECT sub0.min_time,
mytable.*
FROM mytable
INNER JOIN
(
SELECT MIN(`time`) AS min_time
FROM mytable
GROUP BY HOUR(`time`)
) sub0
ON mytable.`time` = sub0.min_time
WHERE DATE(`time`) ="2015-09-12"
ORDER BY `time` ASC
This is using a sub query to get the smallest time in each hour. This is then joined back against your main table on this min time to get the record that has this time.
Note that there is a potential problem here if there are multiple records that share the same time as the smallest one for an hour. There are ways around this, but that will depend on your data (eg, if you have a unique id field which is always ascending with time then you could select the min id for each hour and join based on that)
You can use below query, which is more optimized just make sure that time field should be indexed.
SELECT HOUR(m.time), m.*
FROM mytable AS m
JOIN
(
SELECT MIN(`time`) AS tm
FROM mytable
WHERE `time` >= '2015-09-12 00:00:00' AND `time` <= '2015-09-12 23:59:59'
GROUP BY HOUR(`time`)
) AS a ON m.time=a.tm
GROUP BY HOUR(m.time)
ORDER BY m.time;

MYSQL order by datetime

I need to select one row with the "highest" date and time from a table, but I can't get the highest one, the ORDER BY DESC doesn't work.
Here's my query:
SELECT count(*) as c,
start,
UNIX_TIMESTAMP(start) as S,
duration
FROM appuntamento
WHERE DATE(start) = DATE('2014-04-08 18:30:00')
ORDER BY S DESC
LIMIT 1
I don't care about getting the start value in unix timestamp, it was the nth try to get through this
Any tips?
A few problems here. First, the presence of COUNT(*) turns this into an aggregate query, which do you not want. That's probably the cause of your trouble.
Second, if you have a lot of rows in your appuntamento table the performance of this query will be bad, because you can't use an index.
Presuming that you want the time and duration of the last (latest-in-time) row from a particular day in your table, and the number of appointments for that same day, you need to do this:
SELECT a.start, a.duration, b.count
FROM (
SELECT start,
duration
FROM appuntamento
WHERE start >= DATE('2014-04-08 18:30:00')
AND start < DATE('2014-04-08 18:30:00') + INTERVAL 1 DAY
ORDER BY start DESC, duration DESC
LIMIT 1
) AS a
JOIN (
SELECT COUNT(*) AS count
FROM appuntamento
WHERE start >= DATE('2014-04-08 18:30:00')
AND start < DATE('2014-04-08 18:30:00') + INTERVAL 1 DAY
) AS b
Explanation: First, this form of searching on start allows you to use an index on the start column. You want that for performance reasons.
WHERE start >= DATE('2014-04-08 18:30:00')
AND start < DATE('2014-04-08 18:30:00') + INTERVAL 1 DAY
Second, you need to handle the COUNT(*) as a separate subquery. I have done that.
Third, you can definitely do ORDER BY start DESC and it will work if start is a DATETIME column. No need for UNIX_TIMESTAMP().
Fourth, I used ORDER BY start DESC, duration DESC to arrange to return the longest appointment if there happen to be several with the same start time.
if all you want is one row returned then use the MAX() function without the order. should do the trick.
SELECT count(*) as c,
MAX(start) as highest_date,
UNIX_TIMESTAMP(start) as S,
duration
FROM appuntamento
WHERE DATE(start) = DATE('2014-04-08 18:30:00')
also with your order by statement. you need to add a group by so that you aren't combining incorrect rows with the COUNT() aggregate.
SELECT count(*) as c,
start,
UNIX_TIMESTAMP(start) as S,
duration
FROM appuntamento
WHERE DATE(start) = DATE('2014-04-08 18:30:00')
GROUP BY S
ORDER BY S DESC
LIMIT 1

MySQL: Getting "busiest" or "most popular" hour from a datetime field?

Consider the following table which has the fields - id (int) and date_created (datetime):
id date_created
1 2010-02-25 12:25:32
2 2010-02-26 13:40:37
3 2010-03-01 12:02:22
4 2010-03-01 12:10:23
5 2010-03-02 10:10:09
6 2010-03-03 12:45:03
I want to know the busiest/most popular hour of the day for this set of data. In this example, the result I'm looking for would be 12.
Ideas?
To get just the most popular hour, use this query
select date_format( date_created, '%H' ) as `hour`
from [Table]
group by date_format( date_created, '%H' )
order by count(*) desc
limit 1;
If you want to look at all the data, go with this one
select count(*) as num_records
, date_created
, date_format( date_created, '%H' ) as `hour`
from [Table]
group by `hour`
order by num_records desc;
If you want something a little more flexible, perhaps to the half hour, or quarter hour, you can do the following:
SELECT floor(time_to_sec(date_created)/3600),count(*) AS period
FROM table GROUP BY period ORDER BY c DESC
If you want the most popular 2 hour interval, use 7200. The most popular 15 minute interval, use 900. You just need to remember you are dealing with seconds (3600 seconds in an hour).
Use the hour() function to extract the hour, then do the usual aggregation:
SELECT count(hour(date_created)) AS c, hour(date_created) AS h FROM table GROUP BY h ORDER BY c DESC;
I like both Simon and Peter's answers, but I can't select both as accepted. I combined the 2 to make a cleaner query that only returned the popular hour (I don't need the counts).
SELECT hour(date_created) AS h
FROM my_table
GROUP BY h
ORDER BY count(*) DESC
LIMIT 1
You could try this:
SELECT
DATE_FORMAT(date,'%H') as hours,
count(*) as count
FROM
myTable
GROUP BY
hours
ORDER BY
count DESC