Before i used datetime for post created time from database,
SELECT MONTH(created)+1, count(*)
FROM post_comments
WHERE YEAR(created) = YEAR(CURDATE())
group by MONTH(created)
ORDER BY MONTH(created)
and now i am using unix timestamp. How I need to make a change in the above code, to work it unix timestamp.
Before the created time looks like this: 2018-04-28 09:03:02
and now the created time looks like this: 1524921263
You can convert everything to dates using FROM_UNIXTIME():
SELECT MONTH(FROM_UNIXTIME(created))+1, count(*)
FROM post_comments
WHERE YEAR(FROM_UNIXTIME(created)) = YEAR(CURDATE())
GROUP BY MONTH(FROM_UNIXTIME(created))
ORDER BY MONTH(FROM_UNIXTIME(created));
I find it odd that you are adding 1 to the month in the SELECT.
You can change the WHERE to:
WHERE created >= UNIX_TIMESTAMP(DATE(CONCAT(YEAR(CURDATE), '-01-01')))
In general, it is a good idea to avoid the use of functions on columns. This is less important when you are selecting a significant number of rows (unless the column is a clustered index).
Related
I am using PHP to access a MySQL database. I have a table built up like this:
Table headers:
id (INT, auto increment), profileid, timestamp
Table content:
1, 12345678, 1513814399 (= 12/21/2017)
2, 13451983, 1513814400 (= 12/21/2017)
3, 12345678, 1513944000 (= 12/22/2017)
4, 12345678, 1513944001 (= 12/22/2017)
The table shows which profileids have been called by a website visitor at which time.
So my question is now, how is it possible to show for example:
"Give me the number of entries for profile no. 12345678 called on 12/22/2017", which would be "2" in this case.
I tried it with this query:
SELECT COUNT(profileid), from_unixtime(timestamp, '%d') AS day, from_unixtime(timestamp, '%m') as month, from_unixtime(timestamp, '%Y') as year WHERE profileid='12345678' AND day=22 AND month=12 AND year=2017;
But it is not possible to access the columns "day", "month" and "year" because they to not exist in the table.
Can someone give me a tip how to do this? Another way would be to create three new columns (timestamp_day, timestamp_month and timestamp_year), but that's not a nice solution.
Thank you in advance!
teha
Just produce the date. I think you want:
SELECT COUNT(profileid)
FROM t
WHERE DATE(from_unixtime(timestamp)) = '2017-12-22' AND
profileid = '12345678';
I would be more inclined to write this as:
SELECT COUNT(profileid)
FROM t
WHERE profileid = '12345678' AND
timestamp >= UNIX_TIMESTAMP('2017-12-22') AND
timestamp < UNIX_TIMETAMP('2017-12-23');
This allows the query to make full use of an index on t(profileid, timestamp).
You can use MySQLs DAY, MONTH, and YEAR functions combined with FROM_UNIXTIME.
SELECT COUNT(profileid)
WHERE profileid='12345678'
AND DAY(FROM_UNIXTIME(timestamp))=22
AND MONTH(FROM_UNIXTIME(timestamp))=12
AND YEAR(FROM_UNIXTIME(timestamp))=2017;
A few things here.
You can convert your raw timestamp to a MySQL TIMESTAMP object with FROM_UNIXTIME(timestamp). You already know that.
Once you have a TIMESTAMP you can use all sorts of date functions on it.
You can convert the other direction with UNIX_TIMESTAMP()
When you're looking up records for one day you can do date range searching.
So your query should maybe be
SELECT COUNT(*) cnt
FROM t
WHERE profileid = '12345678'
AND timestamp >= UNIX_TIMESTAMP('2017-12-22')
AND timestamp < UNIX_TIMESTAMP('2017-12-23')
That will pick up every timestamp value on the day you want, up to but not including midnight on the next day. If you have an index on (profileid, timestamp) this kind of query will be fast.
Note you can also do
SELECT COUNT(*) cnt, profileid
FROM t
WHERE timestamp >= UNIX_TIMESTAMP('2017-12-22')
AND timestamp < UNIX_TIMESTAMP('2017-12-23')
GROUP BY profileid
and get a result set showing the counts for all profile ids for that day. And, you can do
SELECT COUNT(*) cnt, profileid, DATE(FROM_UNIXTIME(timestamp)) day
FROM t
WHERE timestamp >= UNIX_TIMESTAMP('2017-11-01')
AND timestamp < UNIX_TIMESTAMP('2017-12-01')
GROUP BY profileid, DATE(FROM_UNIXTIME(timestamp))
and get everything for November.
You can do this
SELECT COUNT(*) cnt, profileid, LAST_DAY(FROM_UNIXTIME(timestamp)) month_ending
FROM t
WHERE timestamp >= UNIX_TIMESTAMP('2017-01-01')
AND timestamp < UNIX_TIMESTAMP('2018-01-01')
GROUP BY profileid, LAST_DAY(FROM_UNIXTIME(timestamp))
and get a month-by-month summary for a whole year.
Date arithmetic is useful. That's why many table designs use actual datestamp-like fields, like DATETIME and TIMESTAMP, rather than raw integer timestamps.
I'm trying to do a SELECT * FROM but only items that are less than 30 days old. Here is my select code:
SELECT * FROM `{$table_name33}` WHERE `type`='wpst-requiredinfo' ORDER BY `foreignkey` ASC;
However, my problem is that I can't figure out how to add WHERE AND last_updated is less than 30 days.
I'm not exactly sure how to write the query, but the date is showing up like this: 1428412603 in the table column, it doesn't look much like a date to me. I don't know where to start.
Try this where clause:
WHERE `type`='wpst-requiredinfo' and
last_updated >= date_sub(now(), interval 30 day)
EDIT:
Your date seems to be in Unix time format.
WHERE `type`='wpst-requiredinfo' and
last_updated >= unixtime_timestamp() - 30*24*60*60
Note: this puts all the functions on the current time. In particular, it does not use FROM_UNIXTIME(last_updated). This ensures that an index can be used for this part of the query. The best index would be on (type, last_updated).
I have a PHP scirpt that is always querying all the data from a database table and it's getting pretty slow. I really just need the data of a specific month and year.
Is there a simple way to get only those entries? For example, everything from February 2013?
The column that stores the dates in my table is of type datetime, if that applies to the solution.
You can add that condition in the WHERE clause of your select statement. I would recommend using BETWEEN operand for two dates:
SELECT myColumns
FROM myTable
WHERE dateColumn BETWEEN '2013-02-01' AND '2013-02-28';
If you mean to say you want everything beginning with February 2013, you can do so using the greater than or equal to operator:
SELECT myColumns
FROM myTable
WHERE dateColumn >= '2013-02-01';
EDIT
While the above are my preferred methods, I would like to add for completeness that MySQL also offers functions for grabbing specific parts of a date. If you wanted to create a paramaterized query where you could pass in the month and year as integers (instead of a start and end date) you could adjust your query like this:
SELECT myColumns
FROM myTable
WHERE MONTH(dateColumn) = 2 AND YEAR(dateColumn) = 2013;
Here is a whole bunch of helpful date and time functions.
You should index the datetime field for added efficiency and then use Between syntax in your sql. This will allow the mysql engine to remove all records that you are not interested in from the returned data set.
I have a table called schedules which contains columns day, month, year, etc. What I need is to select records between the $datefrom and $dateto. Here is my code that does not work :(
SELECT * FROM schedules WHERE CONCAT(year, month, day) BETWEEN $datefrom AND $dateto
Im not sure if this is correct. Please help.
Like showdev already said in a comment, you have to cast the string that is returned from CONCAT() function to date. But consider, that no index can be used on this.
I'd suggest you create an additional column in your table with the full date. I don't know if you separated the date into 3 columns out of performance reasons, but have a try, if only one column is enough for you. Usually it's fast enough (when indexed).
If you don't want to do that and want to use indexes (if they exist at all on those 3 columns) you would have to write the query like this:
SELECT * FROM schedules WHERE
`year` BETWEEN YEAR($datefrom) AND YEAR($dateto)
AND `month` BETWEEN MONTH($datefrom) AND MONTH($dateto)
AND `day` BETWEEN DAY($datefrom) AND DAY($dateto)
I have a database that contains three different columns: domain, date, length (in that order). What I'm trying to do is count the occurrence of every unique date in the database without knowing what the end date is in the database. The start date is always todays date.
So far I've only been able to count the occurences of a specific date, which requires me to put in an exact date.
What I want the PHP script to do is to start with todays date and output the number of times the date is mentioned (or the number of rows with that date) and then continue until it reaches a date that doesn't have a value (you could call this the end date).
I'm surprised and frustrated that I haven't been able to find the solution yet. It seems like a very easy thing to do.
I'd be super happy for any hints, tips or solutions.
Use a combination of a GROUP and WHERE clause.
SELECT COUNT(*) AS `occurrences`, `date` FROM `table` WHERE `date` >= CURDATE() GROUP BY `date`
Use group by and order by
SELECT dateCol, Count(*) FROM myTable
WHERE dateCol >= date(now())
GROUP BY dateCol
ORDER BY dateCol ASC
Edit: SQLFiddle with your example: http://www.sqlfiddle.com/#!2/5e86b/2