MySQL COUNT for days - mysql

I want to get the value of users visiting my page for 10 days in a chart. I need to COUNT() all the values from the last ten days.
The best layout would be
Day|COUNT(ip)
1 - 10
2 - 12
3 - 52
......
I hope you understand what I mean.
Can MySQL do this directly or need I to do this in PHP in 10 seperate querys?
Regards,
Moritz
Update with Tablestructure:
Id (Auto Increment)|Time (Unix Timestamp)|Ip|Referer

This should run fast for you
SELECT COUNT(ip) ipcount,dt FROM
(
SELECT ip,DATE(FROM_UNIXTIME(`Time`)) as dt FROM mytable
WHERE `Time` > TO_UNIXTIME(NOW() - INTERVAL 10 DAY)
) A GROUP BY dt;
Make sure you have an index on Time
ALTER TABLE mytable ADD INDEX TimeIndex (`Time`);

This will give you results with actual date values:
SELECT
COUNT(DISTINCT ip),
FROM_UNIXTIME(Time, '%m/%d/%Y') AS Day
FROM
tbl
WHERE
Time >= UNIX_TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL -10 DAY))
GROUP BY
FROM_UNIXTIME(Time, '%m/%d/%Y')

try this:
SELECT CAST(DATE(FROM_UNIXTIME(`Time`)) AS CHAR) as dateoftime, COUNT(Ip) as cnt
FROM tablename
WHERE DATE(FROM_UNIXTIME(`Time`)) > DATE_SUB(current_timestamp, INTERVAL 10 DAY)
GROUP BY CAST(DATE(FROM_UNIXTIME(`Time`)) AS CHAR)

Related

Getting all previous records of table by date MySQL

My table currently has 21000 records, it's daily updated and almost 300 entries are inserted. Now, what I want is to have a query which will fetch the counts of elements that my table had for the previous 10 days, so it returns:
26000
21300
21000
etc
Right now, I wrote this:
"SELECT COUNT(*) from tbl_task where `task_start_time` < '2020-12-01'"
And it returns 21000 but only for 1 day. I want by query to return records according to 10 days.
However, this does it for only 1 day.
edit : database flavor is mysql and date column is date not datetime
The most efficient method may be aggregation and cumulative sums:
select date(task_start_time) as dte, count(*) as cnt_on_day,
sum(count(*)) over (order by date(task_start_time)) as running_cnt
from tbl_task
group by dte
order by dte desc
limit 10;
This returns the last 10 days in the data. You can easily adjust to more days if you like -- in fact all of them -- without much trouble.
I don't know if I'm wrong, but could you not simple add a GROUP BY - statement? Like:
"SELECT COUNT(*) from tbl_task where `task_start_time` < '2020-12-01' GROUP
BY task_start_time"
EDIT:
This should only work if task_start_time is a date, not if it is a datetime
EDIT2:
If it is a datetime you could use the date function:
SELECT COUNT(*) from tbl_task where `task_start_time` < '2020-12-01' GROUP
BY DATE(task_start_time)
You can use UNION ALL and date arithmetic.
SELECT count(*)
FROM tbl_task
WHERE task_start_time < current_date
UNION ALL
SELECT count(*)
FROM tbl_task
WHERE task_start_time < date_sub(current_date, INTERVAL 1 DAY)
...
UNION ALL
SELECT count(*)
FROM tbl_task
WHERE task_start_time < date_sub(current_date, INTERVAL 9 DAY);
Edit:
You might also join a derived table that uses FROM-less SELECTs and UNION ALL to get the days to look back and then aggregate. This might be a little easier to construct dynamically. (But it may be slower I suspect.)
SELECT count(*)
FROM (SELECT 0 x
UNION ALL
SELECT 1
...
UNION ALL
SELECT 9)
INNER JOIN tbl_task t
ON t.task_start_time < date_sub(current_date, INTERVAL x.x DAY)
GROUP BY x.x;
In MySQL version 8+ you can even use a recursive CTE to construct the table with the days.
WITH RECURSIVE x
AS
(
SELECT 0 x
UNION ALL
SELECT x + 1
FROM x
WHERE x + 1 < 10
)
SELECT count(*)
FROM x
INNER JOIN tbl_task t
ON t.task_start_time < date_sub(current_date, INTERVAL x.x DAY)
GROUP BY x.x;

Mysql query date between in large table

my query is running about 10 seconds and that's unacceptable.
I am looking for a way to improve this speed but i'm out of options.
I have to find the records between now and 30 days back in a table over 12 million rows.
The following query:
SELECT DATE(DATE) AS FDATE,
SUM(VIEW_COUNT) AS COUNT,
COUNT(IP_ADDRESS) AS CLIENTS
FROM VIEWS
WHERE USERID = 'test'
AND DATE BETWEEN ADDDATE(CURDATE(), INTERVAL -30 DAY) AND CURDATE()
GROUP BY FDATE DESC
I also tried, but the same effect:
SELECT DATE(DATE) AS FDATE,
SUM(VIEW_COUNT) AS COUNT,
COUNT(IP_ADDRESS) AS CLIENTS
FROM VIEWS
WHERE USERID = 'test'
AND DATE >= (DATE(NOW() - INTERVAL 30 DAY) + INTERVAL 0 SECOND)
GROUP BY FDATE DESC
You could try using MySQL Indexes for a better performance in decreasing the query execution time.
http://dev.mysql.com/doc/refman/5.7/en/mysql-indexes.html

Query to select record of last five days but in between a specific time

I need to select rows from mdl_logstore_standard_log, the condition is timecreated should be in between last five days 7.30 AM to 4.30PM. How can I achive the combination last 5 days and the time. This is what I have
SELECT * FROM mdl_logstore_standard_log
WHERE FROM_UNIXTIME(timecreated) >= DATE_SUB(CURDATE(), INTERVAL 5 DAY)
GROUP by userid
timecreated is in unixtimestamp
You can do this way too
SELECT
*
FROM mdl_logstore_standard_log
WHERE timecreated >= UNIX_TIMESTAMP(CURDATE() - INTERVAL 5 DAY)
AND (
(timecreated % 86400)
BETWEEN UNIX_TIMESTAMP('1970-01-01 07:30')
AND UNIX_TIMESTAMP('1970-01-01 16:30')
)
GROUP by userid
timecreated % 86400 would return the residue in seconds.
And if the residue lies between 1970-01-01 07:30 and 1970-01-01 16:30 then your condition is actually met.
Note:
Using GROUP BY without aggregate function is discouraged.
(#scaisEdge already stated that)
If you approach this way you take advantage from index on
timecreated field (if any)
PLS try this
SELECT * FROM mdl_logstore_standard_log
WHERE FROM_UNIXTIME(timecreated) >= FROM_UNIXTIME(DATE_SUB(CURDATE(), INTERVAL 5 DAY))
GROUP by userid;
You could use time
SELECT * FROM mdl_logstore_standard_log
WHERE FROM_UNIXTIME(timecreated) >= DATE_SUB(CURDATE(), INTERVAL 5 DAY)
AND time(FROM_UNIXTIME(timecreated))
between time('2016-01-01 07:30:00.0000' ) and time('2016-01-01 16:30:00.0000' )
GROUP by userid
NB you are using group by without aggregation function .. this could retrive not coherent result ..

match timestamp with date in MYSQL using PHP

I have a table
id user Visitor timestamp
13 username abc 2014-01-16 15:01:44
I have to 'Count' total visitors for a 'User' for last seven days group by date(not timestamp)
SELECT count(*) from tableA WHERE user=username GROUPBY __How to do it__ LIMIT for last seven day from today.
If any day no visitor came so, no row would be there so it should show 0.
What would be correct QUERY?
There is no need to GROUP BY resultset, you need to count visits for a week (with unspecified user). Try this:
SELECT
COUNT(*)
FROM
`table`
WHERE
`timestamp` >= (NOW() - INTERVAL 7 DAY);
If you need to track visits for a specified user, then try this:
SELECT
DATE(`timestamp`) as `date`,
COUNT(*) as `count`
FROM
`table`
WHERE
(`timestamp` >= (NOW() - INTERVAL 7 DAY))
AND
(`user` = 'username')
GROUP BY
`date`;
MySQL DATE() function reference.
Try this:
SELECT DATE(a.timestamp), COUNT(*)
FROM tableA a
WHERE a.user='username' AND DATEDIFF(NOW(), DATE(a.timestamp)) <= 7
GROUP BY DATE(a.timestamp);
i think it's work :)
SELECT Count(*)
from table A
WHERE user = username AND DATEDIFF(NOW(),timestamp)<=7

MySql - get days remaining

Users can sign up for a premium listing for a specified number of days, e.g. 30 days.
tblPremiumListings
user_id days created_date
---------------------------------
1 30 2013-05-21
2 60 2013-06-21
3 120 2012-06-21
How would I select records where there are still days remaining on a premium listing.
SELECT *
FROM tblPremiumListings
WHERE created_date + INTERVAL `days` DAY >= CURDATE()
It's easiest to read with INTERVAL
select *
from tblPremiumListings
where created_date + interval days day >= now();
But I would also change the table to instead of created_date and days instead store end_date. That way the query is
select *
from tblPremiumListings
where end_date >= now();
The benefit of doing like this is that you can put an index on end_date and quickly find all ended premium listings, with your original table you'll always have to do a full table scan to find the records with expired listing.
SELECT * FROM
tblPremiumListings
WHERE (DATEDIFF(NOW(), created_date) - days) <= 0
See if it solves your problem
One way to get the result:
SELECT t.user_id
, t.days
, t.created_date
FROM tblPremiumListings t
WHERE t.created_date + INTERVAL t.days DAY > DATE(NOW())
You may want a >= comparison operator (instead of >) depending on how you define days remaining.
NOTE: the access plan for this query will be full scan of all rows, since MySQL won't be able to do a range scan on an index. For large sets, having a column that can be indexed to satisfy the query may improve performance, e.g.
WHERE t.expire_date > DATE(NOW())
Try this one...
SELECT * FROM
tblPremiumListings
WHERE DATE_ADD(created_date, days)>DATE(NOW())