i want to minus purchase date with datenow. i have table named count_sec :
|user_id| purchasedate |second|
| 1 |2015-06-06 08:36:05| |
| 2 |2015-06-06 08:36:15| |
example time now is 2015-06-06 08:37:00
what is the code if i am want the code to update the second to:
|user_id| purchasedate |second|
| 1 |2015-06-06 08:36:05| 55 |
| 2 |2015-06-06 08:36:15| 45 |
thank you
EDIT
i have already create this php, but the code is not work, how to fix?
<?php
require 'database/db.php';
$selectprchsdate = $mysqli->query("SELECT purchasedate FROM count_sec");
$row = mysqli_fetch_assoc($selectprchsdate);
$date = date('Y-m-d H:i:s');
$result = $date - $row['purchasedate'];
$mysqli->query("UPDATE count_sec
SET second = '".$result."'");
?>
In PHP you can use
// get current date and time
$now = new DateTime();
// create DateTime object for purchase date
$purchaseDate = DateTime::createFromFormat('Y-m-d H:i:s', $row['purchasedate']);
// calculate seconds
$seconds = $now->getTimeStamp() - $purchaseDate->getTimeStamp();
But the SQL solution suits this question better.
Try with the SQL query:
SELECT UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(purchasedate) as second from countsec
or this:
SELECT TO_SECONDS(NOW()) - TO_SECONDS(purchasedate) as second from countsec;
From MySQL Date and Time Functions
I am not understanding why you need to store this in a column in the table. As soon as it's stored, the value is old, and it will need to be updated again. (Don't do this.) But setting that issue aside for a moment...
As to why your code isn't "working"... your UPDATE statement is updating every row in the table. You've previously fetched one row from the table, and then calculated one value, and then the UPDATE statement doesn't have a WHERE clause to identify which row(s) you want to update, so every row gets updated with the same value. That's a big part of why your code isn't working.
And, there's no need to run a SELECT statement before you run an UPDATE. If you want to update all rows in the table, you set the column to an expression that returns the number of seconds between the current date and time and the date and time stored in purchasedate column.
One convenient way to do that is to use the UNIX_TIMESTAMP function to convert each of the DATETIME values into an integer value (number of seconds), and subtract them. For example:
UPDATE count_sec
SET `second` = UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(purchasedate)
As an alternative, you could use the TIMESTAMPDIFF function for an equivalent result:
UPDATE count_sec
SET `second` = TIMESTAMPDIFF(SECOND,NOW(),purchasedate)
But back to the issue of why this is wrong. You do not want to store second column in the table.
When you run a SELECT statement to return a row from the table, the value in this column is going to old.
Instead, you could just return a calculated value, calculated as of the time the SELECT statement runs, by including one of those expressions in the SELECT list. For example:
SELECT user_id
, purchasedate
, UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(purchasedate) AS `calc_second`
, `second` AS `old_stored_value`
FROM count_sec
ORDER BY user_id
The point I'm trying to emphasize here... do not store the second value in the table. You'll be chasing it, and continuously updating every row in table, whether that's every five minutes or every five seconds. And the stored value is always going to be "old".
Why do you need that? If you want to find out which rows in the table have second between 60 and 120, for example, if you intend to run this query:
SELECT user_id
FROM count_sec
WHERE second > 120
AND second <= 60
You could just as easily rewrite that based on purchasedate
SELECT user_id
FROM count_sec
WHERE purchasedate > NOW() - INTERVAL 120 SECOND
AND purchasedate <= NOW() - INTERVAL 60 SECOND
And, you won't be "chasing" continuous updates of the rows in the table, generating rollbackup, recording changes in the InnoDB log, writing the UPDATE statements in the binary logs. If you are running replication slaves, those statements have to be read from the log and re-executed on the slaves. All in all, storing second is just a poor design choice.
You can use TIMESTAMPDIFF() function like below. See Documentation
SELECT TIMESTAMPDIFF(SECOND, NOW(), purchasedate)
from count_sec;
(OR) if you want to UPDATE
UPDATE count_sec SET `second` = TIMESTAMPDIFF(SECOND, NOW(), purchasedate);
Per your comment, if you want to delay for 5 minutes then either you can use
SLEEP(seconds) function
(OR)
Wrap your updation code in a stored procedure and run that in every 5 minutes (probably using some scheduler job)
Related
Im trying to avoid multiple sql inserts in a database. The idea is to wait at least 5 minutes before inserting again.
Getting time from last insert using
$query ="SELECT fecha
FROM almacen
WHERE fecha > NOW() - INTERVAL 5 MINUTE
ORDER BY id DESC LIMIT 1"
$espera=mysqli_query($conexion, $query)
if (empty($espera)) { inserting code } else { close }
But the query returns nothing when it should be returning a value. I was thinking it might be a problem since date was inserted using php date ( "j/n/Y h:i");
Should i change the time format? what should i use?
If you wanted to restrict your rows to only 1 entry per 5 minutes I would:
Create a column called insert_interval DATE and create a unique index on that column. Then just attempt your insert, setting the value of insert_interval to
whatever 5 minute interval the insert time falls under.
E.G. Normalize date to 5 minute interval.
select now() - interval (mod(minute(now()),5)) minute - interval second(now()) second;
Insert
insert into table(columns ..., insert_interval) values(
..., now() - interval mod(minute(now()),5) minute - interval second(now())
);
Only 1 row is allowed per 5 minute interval starting on the hour. So 1 row from 00:00:00 - 00:04:59, and so on. Any attempt to insert another row in that time window, would result in a duplicate key error, that you can catch and take appropriate action.
SQL Fiddle
Uncomment the last insert to see the error on build schema.
I am trying to update a MySQL table with an 'expiration date'. I've collected a timestamp value for all my rows as people have registered into the table but now I want to create an expiration date relative to that timestamp (not to relative to the current time). Here's my code:
$timestamp = $row['timestamp'];
$sql_update = "
UPDATE jobs
SET expiration_date = DATE_ADD('$timestamp',INTERVAL 56 DAY)";
$result_update = $mysqli->query($sql_update) or die($mysqli->error);
Understand that this is being run in a 'while' loop so it's running through each row of the table an updating them as it goes. The issue is that I ran it once and all it did was update the 'expiration_date' row to 56 days from NOW not 56 days from the timestamp's value. The timestamp is set on CURRENT_TIMESTAMP for when the a new entry is registered which I'm assuming is the problem. I've echoed out $timestamp to troubleshoot and it echoes out the correct value (not the current time) when I echo it but when it goes to actually update the expiration date it seems to be drawing from the fact that it's a CURRENT_TIMESTAMP. Is there a way to explicit query for the value of the timestamp?
I'm hoping to find a way that doesn't involved restructuring the database. I know I could have it so instead of a timestamp row, I could make it a datetime row and set it to the value of NOW() when database is being initially queried to add a row but I'd prefer to find a solution within the way the table is currently set up. Thanks!
Probably somehow the value in $timestamp is wrong.
Try adding the timestamp directly in the query using the column name. E.g. : DATE_ADD(timestamp,INTERVAL 56 DAY)
What you are currently doing, hardly makes any sense. You first get the timestamp from the database and assign it to the $timestamp variable, only to use it in the query again..
In situations like these, you can better directly use the column name to access the data in your query.
I wonder why are you running this query in loop ?
You can use only one sql statement. Update from select;
update jobs a set a.expiration_date = DATE_ADD(a.timestampFieldName,INTERVAL 56 DAY), a.timestampFieldName = a.timestampFieldName;
I supose that there is some "bug" (don't know) in MySQL because if you don't add a.timestampFieldName = a.timestampFieldName then this field will be set to current timestamp;
So I have a MySQL table that looks something like this:
id timestamp action timePassed
1 2012-07-10 22:44:00 start 0
2 2012-07-10 22:44:50 pause 50
3 2012-07-10 22:45:30 play 50
4 2012-07-10 22:47:25 pause 205
5 2012-07-10 22:48:05 play 205
I don't know how obvious it is but what's happening here is basically on every 'pause' row I am calculating the difference in seconds between the current timestamp and the timestamp of the 'start' row.
The only way I can think of doing this is to INSERT a new 'pause' row into the database so the timestamp is generated...then query the database for the timestamp of that 'pause' row...calculate the difference in seconds between that 'pause' row and the 'start' row using PHP...then UPDATE the 'pause' row with the timePassed result.
My question is whether or not there is a better way to do this (i.e. using timediff or some other MySQL command). The issue is the 'pause' timestamp doesn't exist until I make the INSERT, so I feel like that needs to happen first before I can make any calculation?
Well if your table is like this and your requirement is like this then you are on track..
However better if you check the second difference between last row and last to last row. This will give you idea for how many second user has PAUSED or Played the TRACK.
INSERT INTO table (timestamp, action, timePassed)
SELECT now(), 'pause', SECOND(timediff(now(), timestamp))
FROM table
WHERE ID = (Select Max(ID) from Table)
Put action as you like so you can insert time difference between two.
The only way I can think of doing this is to INSERT a new 'pause' row
into the database so the timestamp is generated...then query the
database for the timestamp of that 'pause' row...calculate the
difference in seconds between that 'pause' row and the 'start' row
using PHP...then UPDATE the 'pause' row with the timePassed result.
You can INSERT the already calculated row.
INSERT INTO table (timestamp, action, timePassed)
SELECT now(), 'pause', SECOND(timediff(now(), timestamp))
FROM table
WHERE action = 'start'; -- and/or other WHERE clauses.
This will introduce a skew in time due to the time needed to retrieve the 'start' row (but with index on action (and maybe timestamp if the row is very large), that time should be negligible).
I would recommend not storing timePassed explicitly at all, since by having each event's timestamp, you already have every interval stored once. If you separately store timePassed, you'll be storing the same data in multiple places. To quote E. F. Codd, "If something is true, saying it twice doesn't make it any more true." Also, you're subject to update anomalies when you store the same thing multiple times.
If you want to calculate the interval with a query, this might work.
SELECT event.id,
event.timestamp,
event.action,
TIME_TO_SEC(TIMEDIFF(event.timestamp, start_event.timestamp)) time_passed
FROM event
JOIN (SELECT timestamp
FROM event
WHERE event.action = 'start') start_event ON 1 = 1
I want to add a row to a db with a time 'x' amount into the future (different for each row). I have looked through every tutorial/help/whatever I could find via google but nothing seems to help.
From what I can tell, the best way is to do it with MySQL.
SELECT ADDTIME(now(), '00:10:00')
But how do I actually make that work with this:
$new_row = $db->prepare("INSERT INTO table (field1, field2, time) VALUES(?, ?,?)");
$new_row->execute(array($field1, $field2, $timeintenminutes)) or dieWithDBError($new_row);
Untested, but have you tried:
$new_row = $db->prepare("INSERT INTO table (field1, field2, time) VALUES(?, ?, ADDTIME(NOW(), '00:10:00'))");
$new_row->execute(array($field1, $field2)) or dieWithDBError($new_row);
What is the column type of time?
In PHP, you can simple do that $AddSomeTime=time() + 60; which will add 1 minute from now.
I presume want that instead of updating the MySQL table? If you want to work with MySQL update query, than use UPDATE YourTable SET valuet=(ADDTIME(now(), '00:10:00')) WHERE id=$id;
$future_time = date("Y-m-d H:i:s",time()+60*10);
This will get you the 10 minute added time.
In Php strtotime() will do the trick for adding values to time or date
$1hrInFuture = strtotime('now +1 hours');
str2time (now); will understand now as the server's current time, and will add 1 hrs to it, you can add +1 weeks, +1 months...etc.
to make it formatted correctly, use the date:
$1hrInFutureF = date('Y-m-d H:i:s',$1hrInFuture);
this example will get the current servers date, and add 1hr to it;
Note: not using 'now' in the strtotime will generate the date 'January 1 1970 00:00:00 UTC';
Now you can get the date from the database, insert it into the strtotime, add 1 hr to it, format it the way you want, and insert it back to a new column.
and for the different timezone between the mysql n the server, you can create a column in that db, set a randdom hash inside the inserted row, the select that row's normal_date, and insert the +1 hr date using the current_time_stamp and the random number
INSERT INTO X (title,rnd_nb) VALUES ('titke','rnd_nb);
SELECT ID FROM X WHERE rnd_nb = $rnd_nb(php variable inside the function);
UPDATE `x` SET (1hrplus_date='$the_variable_containing_the_future_time') WHERE id='the_id_grabbed_from_the_second_query);
So if you see, we inserted a random number there,automaticaly if its the currenttimestamp, it will add the current_time_stamp..etc and selected the row containing that number, got it's id, , then get the currenttimestamp, put it in the strtotime function to add 1 hr to it, update that row, and set the +1hrcolumn using the strtotime output.
Hope that's useful :)
For simplicity sake, I have two fields within a table:
Date 1 (YYYY-MM-DD format)
Day (single or two digit day format, 1-31)
I want to be able to update Date 1 using the value within Day but I DO NOT want to make multiple calls to do so (first a select, fetch results, then update with the result from the same table).
ultimately, the 'design' of my call (which does not work) would be:
UPDATE table SET Date 1 =
DATE(Y-(M+1)-(value of Day));
or in php:
date("Y-m-d", mktime(0,0,0,date('m')+1, VALUE(Day), date('Y')));
is this possible?
UPDATE
==
While I have been able to utilize some of the code below, I am not sure MYSQL is 'smart' enough to run the calculation as I have it. My new code is:
UPDATE table SET Date 1=
CONCAT(YEAR(CURDATE()),'-',MONTH(ADDDATE(CURDATE(),
INTERVAL 1 MONTH)),'-',Day1)
While this returns the correct 'new month' and 'new day', the year will be wrong WHEN the current month is December.
For example: If the current date is 2010-12-02. The preferred data in the Day field is 12. Once our script has processed, the Date 1 field should be updated to 2011-01-12 but in the code above it will only output to 2010-01-12.
not tested, but i think what you're missing is CONCAT:
UPDATE table SET datefield = CONCAT(YEAR(datefield),'-',MONTH(datefield),'-',dayfield);
after rereading you questioon, it sounds like you want to add the days, that would be like this (not tested, too - take a look at DATE_ADD and INTERVAL):
UPDATE table SET datefield = DAT_ADD(datefield, INTERVAL dayfield DAYS);