I am trying to write an SQL query to return how many links were submitted to my website over the last 7 day period. So far I have this:
SELECT COUNT(`id`) AS `count`
FROM `links`
WHERE `created` > NOW() - 86400
AND `created` < NOW()
this works for one day, it returns one row called count with the number of links submitted in the last 24 hours. I need to change it to return 2 columns called date and count, with 7 rows (one for each day).
The tricky part that I can't get my head around is that created is a timestamp column, and I don't have access to change it so I have to work with it.
Edit: work in progress for the query:
SELECT DAY(FROM_UNIXTIME(created)) AS day, COUNT(id) count
FROM links
GROUP BY DAY(FROM_UNIXTIME(created))
LIMIT 7
NOW() actually shouldn't be working as it returns a datetime. Also, if you want to fetch 7 days worth of data, you want to subtract 604800 from UNIX_TIMESTAMP(). You can use then date and time functions with FROM_UNIXTIME. This will make grouping easier. Optimally, your column should be of datetime type.
It would go something like:
SELECT DAY(FROM_UNIXTIME(created)) day, COUNT(id) count
FROM links
WHERE created > UNIX_TIMESTAMP() - 604800 AND created < UNIX_TIMESTAMP()
GROUP BY DAY(FROM_UNIXTIME(created))
You can alternatively use the BETWEEN operator:
WHERE created BETWEEN UNIX_TIMESTAMP() - 604800 AND UNIX_TIMESTAMP()
See the demo
Related
I have a table which has a column called created DATETIME, When adding entries It works fine, but when It gets to Date Interval, It keeps on duplicating new entries. I'm trying to get Today's and Yesterday's entries. Today's works fine, but for Yesterday's, It also puts on Today's contents in query results which Is not what I want.
SELECT * FROM tab WHERE created > DATE_SUB(NOW(), INTERVAL $num DAY) ORDER BY created DESC LIMIT 9;
$num Is 1 for Today's entries, and It's 2 for Yesterday's. So basically an entry which Is created today, Is getting duplicated on Yesterday's query results.
You are getting the results you requested from the database. Namely any record that is greater than today minus however many days you put in.
The reason you get 0 records when you try #KenWhite's suggested of changing your > to = is because your field is DATETIME, so subtracting exactly 24 hours from NOW() yields the same exact time yesterday and you probably don't have a record that was written precisely at this time yesterday. Right?
What you'll have to do is test for records between two dates to get you want. Instead of NOW(), switch to CURDATE(), this way you can be assured you'll get every record for the datetime range you are looking for.
SELECT *
FROM tab
WHERE
created BETWEEN DATE_SUB(CURDATE(), INTERVAL $num DAY) AND DATE_SUB(CURDATE(), INTERVAL $num - 1 DAY)
ORDER BY created DESC LIMIT 9;
You can check out a SQLFiddle of this here: http://sqlfiddle.com/#!2/19d9b/12
With datetime/timestamp values, similar to floats, always use ranges with closed beginnings and open endings. So use '>=' and '<'.
For example to use the data of a single day:
SELECT ... FROM tab
WHERE created >= CURDATE() - INTERVAL #num:=? DAY
AND created < CURDATE() - INTERVAL #num DAY + INTERVAL 1 DAY
ORDER BY created DESC
LIMIT 9
;
With MySQL, generally prefer the timestamp type over the datetime type, as datetime doesn't carry timezone information.
Alternatives:
created_at timestamp NULL DEFAULT NULL COMMENT 'set by application',
created_at timestamp NOT NULL DEFAULT '1970-01-01 23:00:00' COMMENT 'set by application',
dbms_row_created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'set by DBMS',
I am trying to create a query that will limit insertion into a table based on the last time the poster sent data to the table.
For example if you posted data to the table then you are locked out of the system for another 10 hours. Here is what I came up with so far. But I get nowhere with the actual results on the data. Any help?
SELECT DATE( `date` )
FROM tablename
WHERE DATE( CURDATE( ) ) < CURDATE( ) - INTERVAL 1002
DAY
LIMIT 0 , 30
This will return a single post from the last 10 hours, if it exists:
SELECT *
FROM tablename
WHERE `date` >= NOW() - INTERVAL 10 HOUR
LIMIT 1
I'm assuming date is declared as DATETIME, since actual DATE does not contain the time part and hence is only day-accurate.
If date is an integer UNIX timestamp, use this:
SELECT *
FROM tablename
WHERE `date` >= UNIX_TIMESTAMP(NOW() - INTERVAL 10 HOUR)
LIMIT 1
There are a number of ways you could do this. Perhaps if you have a user settings table you could simply add a "last_insert" field, and store the timestamp as an integer value- that would be a super simple way to do it- you could check the current timestamp vs user_settings.last_insert and voila!
I suppose you could use datetime too. Whatever floats the boat.
First of all, you need a DATETIME column and not a DATE column. Assuming that tablename.date is a DATETIME column, then 10 hours before right now is CURRENT_TIMESTAMP - INTERVAL 10 HOUR.
First of all create a Time (TIMESTAMP DEFAULT CURRENT_TIMESTAMP) columnt in your table. It will be automatically set to current date on row insert
Then check:
SELECT COUNT(*) FROM Table WHERE Time > NOW() - INTERVAL 10 HOUR
If its 1 or more - block
You must compare the time last post was put with current time, not current time with current time :|
I have the following table:
CREATE TABLE account (
account_id bigint(20) NOT NULL AUTO_INCREMENT,
time_start datetime NOT NULL,
time_end datetime DEFAULT NULL,
PRIMARY KEY (account_id),
KEY idx_start (account_id,time_start),
KEY idx_end (account_id,time_end)
) ENGINE=MyISAM
How can I write a query to find how many users log on monthly?
I want to find for the last 90 days how many different account_id are in the table group by month. Group by month means here every 30 days: for example from 2011-12-05 to 2011-11-06, from 2011-12-04 to 2011-11-05 and so on for the last 90 days.
You can trivially get years/months out of a datetime field with YEAR() and MONTH() respectively. But your periods don't match start/end on month boundaries, so you'll need some ugly-looking query logic to handle that conversion.
You should start by writing a stored function/procedure that'll convert a regular date/time to a "fiscal" date time, after which the query should become much cleaner looking. Once you've got the procedure done, it can be reused everywhere, as fiscal period calculations will undoubtedly be repeated elsewhere as well.
This query assumes two things:
1) you have your month logic squared-away (see #Marc's post) and added as an extra column (month) on the table.
2) time_start is the time that the user has "logged-on".
SELECT COUNT(*), month
FROM account
GROUP BY month
HAVING time_start > ADDDATE(CURDATE(),- INTERVAL 90 DAY);
Try messing around with it and see if that helps. I'm not too sure on the negative ADDDATE bit there, so you'll want to check-out MySQL's reference page for date and time functions.
try this
select count(distinct account_id)
from account
where
time_start >= date_sub(now(), interval 90 day)
group by
floor(datediff(now(), time_start) / 30)
I have a database with several tables. Each of these tables has a column 'created' which contains time-stamps of when that particular row was created in the database.
Now, I want to create a MySQL script that checks once every week if there is data coming into these tables. So, there should be data coming everyday. How do I create a MySQL script that allows me to do this for all the tables in the database?
Note: Remember I want to do this for all the tables in the database with a single script. That's the main thing I want to know.
i use this approach for a table called call, with a column of timestamp type called systemdate:
SELECT * FROM `call` WHERE DATE(`systemdate`) = DATE(NOW());
mysql DATE() statement gets the datepart of a datetime or timestamp field.
Sorry, just noticed that you want to check if atleast there is an entry for each of the days in the previous week.
you can use this query to check the prevous days individually:
yesterday:
SELECT * FROM `call` WHERE DATE(`systemdate`) = DATE(NOW()) - 1;
before yesterday:
SELECT * FROM `call` WHERE DATE(`systemdate`) = DATE(NOW()) - 2;
Or you can check the whole week at once:
SELECT * FROM `call` WHERE DATE(`systemdate`) > DATE_SUB(CURDATE(), INTERVAL 7 DAY) GROUP BY DATE(`systemdate`);
This will return one result for each day, so if you have 7 results you'll know at least an entry was made on each day.
select * from table
where created between subdate(current_date, interval 7 day) and current_date;
Selecting datetimes up to current_date includes everything up to the start of "today" (ie "the previous midnight").
I am having fields called 'timestamp','onlineuser' from table called 'User'. I need to select onlineuser who is having the timestamp which is less than 5 minutes between NOW(),timestamp.
For example, timestamp will be like 2011-06-20 16:02:22.
I tried with mysql query , but seems wrong. kindly help me
SELECT * FROM user WHERE timestamp >= NOW() - INTERVAL 5 MINUTE