Inserting seconds into a database in HH:MM:SS format - mysql

I have a JavaScript timer on a PHP page. It returns a number, representing seconds, that I want to insert into a database column of type Time. How can I do that?
This code is the best I could find:
$query = "INSERT INTO #__quiz_r_student_question (c_stu_quiz_id,
c_question_id,
c_score,
c_attempts,
is_correct,
time_to_solve
)" .
"\n VALUES('".$stu_quiz_id."',
'".$quest_id."',
'".$c_quest_score."',
'".($c_quest_cur_attempt + 1)."',
'".$is_correct."',
DATEADD(ms, ".$time_to_solve."* 1000, 0)
)";

This answer was originally posted by the asker as an edit to the question.
I solved my problem with PHP, not an SQL query. I used this code to change my seconds value into a readable time ready for database insertion:
$time = gmdate('H:i:s',$time_to_solve)

You can use a SEC_TO_TIME function. Take a look at this script -
CREATE TABLE table_time(
column1 TIME DEFAULT NULL
);
INSERT INTO table_time VALUES(SEC_TO_TIME(3600));
SELECT * FROM table_time;
+----------+
| column1 |
+----------+
| 01:00:00 |
+----------+

Related

Different Date Format in BETWEEN condition

Im newbie for sql. My code:
$start_date='2017-01-01';
$end_date='2016-01-31';
$this->db->where('date_note BETWEEN "'. date('Y-m-d', strtotime($start_date)). '" and "'. date('Y-m-d', strtotime($end_date)).'"');
But in my database is like 2016-03-11 14:21:36
How I can get this record from database with different format date? Thanks
The MySQL function DATE_FORMAT() resolves fully your problem as it allows you to get the time you saved within your database in the format of your choice.
There is no problem in your SQL. It is okay to compare DATE with DATATIME(as in your database).
Here is a demo:
mysql> SELECT '2016-03-11 14:21:36' BETWEEN '2016-03-10' AND '2016-03-12';
+-------------------------------------------------------------+
| '2016-03-11 14:21:36' BETWEEN '2016-03-10' AND '2016-03-12' |
+-------------------------------------------------------------+
| 1 |
+-------------------------------------------------------------+
1 row in set (0.00 sec)

Regular expressions on strings in SQL statement

I have a table with following columns and sample data
File Name | Status
'xxx_2015-07-20.csv' | Completed
'xxx_2015-07-19.csv' | Completed
'xxx_2015-07-18.csv' | Failed
.
.
'xxx_2015-06-01.csv' | Failed
Now I have two scenarios in my application (PHP-MySQL):
1) I have to fetch the status of today's file. I can do it like this:
select status from myTable where file_name like '%date(Y-m-d)%';
2) I want to fetch the status of all files generated since 1 month from today. Suppose today is 2015-07-20, then files from 2015-06-20 should show up.
Since there is no date column, I can't apply comparison operator and get the results. I believe it will need some playing with regular expressions.
I am not familiar with regular expressions, so any help on this would be much appreciated.
If the pattern is same i.e. xxx_2015-07-20.csv you can use substring_index function to get the date value as
mysql> select substring_index(substring_index('xxx_2015-07-20.csv','_',-1),'.',1) as d;
+------------+
| d |
+------------+
| 2015-07-20 |
+------------+
Now using the same you can have the select statement as
select status from myTable
where
substring_index(
substring_index(file_name,'_',-1),
'.',1
) = curdate();

how to return only query time and not the data

I use the SQuirreL application from sourceforge to query and extract info from my data sources. Some of the data though are huge and I don't really need to see it, I am only interested in how long it took to run the whole query.
So I am wondering if there is any command in SQL that I can add to a SELECT statement to run the query but not bring back any data just the time that it took to retrieve the data?
Thanks
You can use MySQL Query profiler to do something similar:
mysql> set profiling=1;
select * from table;
mysql> show profiles;
This should show you something like:
+----------+------------+-----------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-----------------------------------------------+
| 0 | 0.00007300 | set profiling=1 |
| 1 | 0.00044700 | select * from table; |
+----------+------------+-----------------------------------------------+
2 rows in set (0.00 sec)
Alternately you could do something hacky with microtime(), something like:
// Grab the start time
$start = microtime(true);
// Execute your query
mysql_query('select * from table');
// Do something with the execution time
echo microtime(true) - $start .' seconds';
But obviously this is far from ideal (and you shouldn't be using mysql_*)!

How can I show the query time in Perl, DBI?

I use Perl and DBI to manage my MySQL tables, querys, etc. How can I show the running time of a query?
If I do a SELECT in the console, the result will be like this:
+-----+-------------+
| id | name |
+-----+--------------
| 1 | Jack |
| 2 | Joe |
| 3 | Mary |
+-----+-------------+
3 rows in set (0.17 sec)
I need to show 0.17 sec. There is any way in DBI to show the running time in Perl, something like this?
my $dbh = $db->prepare("SELECT id, name FROM names ORDER BY id;");
$dbh->execute;
print $dbh->runnin_time; # ???
DBI#Profile, DBI::Profile, DBI::ProfileData, DBI::ProfileDumper, dbiprof
You take a timestamp before you run the query, and a timestamp after. The difference is your query execution time. For obtaining high-resolution timestamps, see Time::HiRes
I can't find anything in DBI. I think that there is nothing already implemented out of the box, though could be interesting information.
The other way to do this would be to get the time before and after the execution and then make a simple difference. You can do it from within your Perl script simply getting the time stamp before the query execution, and after, then subtract the two to find the execution time.
my $start = DateTime->now;
my $dbh = $db->prepare("SELECT id, name FROM names ORDER BY id;");
$dbh->execute;
my $end = DateTime->now;
my $elapsedtime = ($end->subtract_datetime($start))->seconds;
print "Execution time(seconds) : $elapsedtime \n";
Using Time::HiRes could also be an easy way to find the query time. Here is an example that uses Time::HiRes:
use Time::HiRes;
$start_time = Time::HiRes::gettimeofday();
my $dbh = $db->prepare("SELECT id, name FROM names ORDER BY id;");
$dbh->execute;
$end_time = Time::HiRes::gettimeofday();
my $elapsedtime = sprintf("%.6f", $end_time - $start_time);
print "Execution time(seconds) : $elapsedtime \n";
Reading #daxim's links to documentation, there is a simple way to achieve this by running your script with DBI_PROFILE=2 which is from DBI::Profile
Example output:
DBI::Profile: 53.203692s 50.67% (6725 calls) script.pl # 2016-01-21 11:51:49
'INSERT INTO FOO ("BAR") VALUES (?)' =>
0.057596s / 2 = 0.028798s avg (first 0.051621s, min 0.005975s, max 0.051621s)
'INSERT INTO BAZ ("QUX") VALUES (?)' =>
0.367184s / 44 = 0.008345s avg (first 0.039410s, min 0.002445s, max 0.039410s)

How can I tell when a MySQL table was last updated?

In the footer of my page, I would like to add something like "last updated the xx/xx/200x" with this date being the last time a certain mySQL table has been updated.
What is the best way to do that? Is there a function to retrieve the last updated date? Should I access to the database every time I need this value?
In later versions of MySQL you can use the information_schema database to tell you when another table was updated:
SELECT UPDATE_TIME
FROM information_schema.tables
WHERE TABLE_SCHEMA = 'dbname'
AND TABLE_NAME = 'tabname'
This does of course mean opening a connection to the database.
An alternative option would be to "touch" a particular file whenever the MySQL table is updated:
On database updates:
Open your timestamp file in O_RDRW mode
close it again
or alternatively
use touch(), the PHP equivalent of the utimes() function, to change the file timestamp.
On page display:
use stat() to read back the file modification time.
I'm surprised no one has suggested tracking last update time per row:
mysql> CREATE TABLE foo (
id INT PRIMARY KEY
x INT,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP,
KEY (updated_at)
);
mysql> INSERT INTO foo VALUES (1, NOW() - INTERVAL 3 DAY), (2, NOW());
mysql> SELECT * FROM foo;
+----+------+---------------------+
| id | x | updated_at |
+----+------+---------------------+
| 1 | NULL | 2013-08-18 03:26:28 |
| 2 | NULL | 2013-08-21 03:26:28 |
+----+------+---------------------+
mysql> UPDATE foo SET x = 1234 WHERE id = 1;
This updates the timestamp even though we didn't mention it in the UPDATE.
mysql> SELECT * FROM foo;
+----+------+---------------------+
| id | x | updated_at |
+----+------+---------------------+
| 1 | 1235 | 2013-08-21 03:30:20 | <-- this row has been updated
| 2 | NULL | 2013-08-21 03:26:28 |
+----+------+---------------------+
Now you can query for the MAX():
mysql> SELECT MAX(updated_at) FROM foo;
+---------------------+
| MAX(updated_at) |
+---------------------+
| 2013-08-21 03:30:20 |
+---------------------+
Admittedly, this requires more storage (4 bytes per row for TIMESTAMP).
But this works for InnoDB tables before 5.7.15 version of MySQL, which INFORMATION_SCHEMA.TABLES.UPDATE_TIME doesn't.
I don't have information_schema database, using mysql version 4.1.16, so in this case you can query this:
SHOW TABLE STATUS FROM your_database LIKE 'your_table';
It will return these columns:
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
As you can see there is a column called: "Update_time" that shows you the last update time for your_table.
The simplest thing would be to check the timestamp of the table files on the disk. For example, You can check under your data directory
cd /var/lib/mysql/<mydatabase>
ls -lhtr *.ibd
This should give you the list of all tables with the table when it was last modified the oldest time, first.
For a list of recent table changes use this:
SELECT UPDATE_TIME, TABLE_SCHEMA, TABLE_NAME
FROM information_schema.tables
ORDER BY UPDATE_TIME DESC, TABLE_SCHEMA, TABLE_NAME
I would create a trigger that catches all updates/inserts/deletes and write timestamp in custom table, something like
tablename | timestamp
Just because I don't like the idea to read internal system tables of db server directly
Although there is an accepted answer I don't feel that it is the right one. It is the simplest way to achieve what is needed, but even if already enabled in InnoDB (actually docs tell you that you still should get NULL ...), if you read MySQL docs, even in current version (8.0) using UPDATE_TIME is not the right option, because:
Timestamps are not persisted when the server is restarted or when the
table is evicted from the InnoDB data dictionary cache.
If I understand correctly (can't verify it on a server right now), timestamp gets reset after server restart.
As for real (and, well, costly) solutions, you have Bill Karwin's solution with CURRENT_TIMESTAMP and I'd like to propose a different one, that is based on triggers (I'm using that one).
You start by creating a separate table (or maybe you have some other table that can be used for this purpose) which will work like a storage for global variables (here timestamps). You need to store two fields - table name (or whatever value you'd like to keep here as table id) and timestamp. After you have it, you should initialize it with this table id + starting date (NOW() is a good choice :) ).
Now, you move to tables you want to observe and add triggers AFTER INSERT/UPDATE/DELETE with this or similar procedure:
CREATE PROCEDURE `timestamp_update` ()
BEGIN
UPDATE `SCHEMA_NAME`.`TIMESTAMPS_TABLE_NAME`
SET `timestamp_column`=DATE_FORMAT(NOW(), '%Y-%m-%d %T')
WHERE `table_name_column`='TABLE_NAME';
END
OS level analysis:
Find where the DB is stored on disk:
grep datadir /etc/my.cnf
datadir=/var/lib/mysql
Check for most recent modifications
cd /var/lib/mysql/{db_name}
ls -lrt
Should work on all database types.
a) It will show you all tables and there last update dates
SHOW TABLE STATUS FROM db_name;
then, you can further ask for specific table:
SHOW TABLE STATUS FROM db_name like 'table_name';
b) As in above examples you cannot use sorting on 'Update_time' but using SELECT you can:
SELECT * FROM information_schema.tables WHERE TABLE_SCHEMA='db_name' ORDER BY UPDATE_TIME DESC;
to further ask about particular table:
SELECT * FROM information_schema.tables WHERE TABLE_SCHEMA='db_name' AND table_name='table_name' ORDER BY UPDATE_TIME DESC';
I got this to work locally, but not on my shared host for my public website (rights issue I think).
SELECT last_update FROM mysql.innodb_table_stats WHERE table_name = 'yourTblName';
'2020-10-09 08:25:10'
MySQL 5.7.20-log on Win 8.1
Just grab the file date modified from file system. In my language that is:
tbl_updated = file.update_time(
"C:\ProgramData\MySQL\MySQL Server 5.5\data\mydb\person.frm")
Output:
1/25/2013 06:04:10 AM
If you are running Linux you can use inotify to look at the table or the database directory. inotify is available from PHP, node.js, perl and I suspect most other languages. Of course you must have installed inotify or had your ISP install it. A lot of ISP will not.
Not sure if this would be of any interest. Using mysqlproxy in between mysql and clients, and making use of a lua script to update a key value in memcached according to interesting table changes UPDATE,DELETE,INSERT was the solution which I did quite recently. If the wrapper supported hooks or triggers in php, this could have been eaiser. None of the wrappers as of now does this.
i made a column by name : update-at in phpMyAdmin and got the current time from Date() method in my code (nodejs) . with every change in table this column hold the time of changes.
Same as others, but with some conditions i've used, to save time:
SELECT
UPDATE_TIME,
TABLE_SCHEMA,
TABLE_NAME
FROM
information_schema.tables
WHERE
1 = 1
AND UPDATE_TIME > '2021-11-09 00:00:00'
AND TABLE_SCHEMA = 'db_name_here'
AND TABLE_NAME not in ('table_name_here',)
ORDER BY
UPDATE_TIME DESC,
TABLE_SCHEMA,
TABLE_NAME;
This is what I did, I hope it helps.
<?php
mysql_connect("localhost", "USER", "PASSWORD") or die(mysql_error());
mysql_select_db("information_schema") or die(mysql_error());
$query1 = "SELECT `UPDATE_TIME` FROM `TABLES` WHERE
`TABLE_SCHEMA` LIKE 'DataBaseName' AND `TABLE_NAME` LIKE 'TableName'";
$result1 = mysql_query($query1) or die(mysql_error());
while($row = mysql_fetch_array($result1)) {
echo "<strong>1r tr.: </strong>".$row['UPDATE_TIME'];
}
?>
Cache the query in a global variable when it is not available.
Create a webpage to force the cache to be reloaded when you update it.
Add a call to the reloading page into your deployment scripts.