Mysql: how to reuse a calculation within a query - mysql

I have a query below that I use to retrieve the records not updated for a given time (in hours) and order it by elapsed time:
SELECT TABLE.Key, TIMESTAMPDIFF(HOUR, TABLE.Date_last_consulted, CURRENT_TIMESTAMP)
FROM TABLE WHERE TIMESTAMPDIFF(HOUR, TABLE.Date_last_consulted,
CURRENT_TIMESTAMP) <= 7 ORDER BY TIMESTAMPDIFF(HOUR, TABLE.Date_last_consulted,
CURRENT_TIMESTAMP);
As you can see, it calls multiple times TIMESTAMPDIFF, which is not very efficient as all these calls lead to useless SQL calculations.
I was wondering if there were a way to reuse the calculations so it is processed only once?
Thanks a lot for your help.
Florent

SELECT
t.Key, t.dif
FROM (
SELECT key, TIMESTAMPDIFF(HOUR, TABLE.Date_last_consulted, CURRENT_TIMESTAMP) dif
FROM TABLE
) t
WHERE
t.dif <= 7
ORDER BY
t.dif

Related

SQL compare using between for separated Date and Time Column

I have two columns.
CREATED_DATE || CREATED_TIME
And I want to write a query to get records between these columns.
I wrote below query but it fails because of time column.
SELECT *
FROM TABLE
WHERE (CREATE_DATE BETWEEN '1982-10-21' AND '2015-02-25')
`AND (CREATE_TIME BETWEEN '14:00:00' AND '15:00:00')
However if requested_start_date >= created_date and requested_end_date =< created_date it then SQL should not compare time columns.
How can i handle it?
Thank you
Regeards
select *from TABLE
where CAST(CREATE_TIME as time) >= '14:00:00'
or CAST(CREATE_TIME as time) < '15:00:00'
try this for time comparision

MySQL query: get data in specific interval

I have a MySQL Table with one datetime column. I want to prevent that the PHP-script gets to much data. So i'm searching for a solution that a MySql query only selects rows which have a distance of 1 minute or whatever. is there something simple or do i have to code a for-loop with a new mysql query every time.
Example
timestamp
2012-09-25 00:00:00-->
2012-09-25 00:00:50
2012-09-25 00:01:23
2012-09-25 00:01:30-->
2012-09-25 00:02:33
2012-09-25 00:02:40
2012-09-25 00:03:01-->i want those
thanks in advance
Try this :
SELECT create_time
FROM timeTable
WHERE create_time
IN (
SELECT min( create_time )
FROM timeTable
GROUP BY FROM_UNIXTIME( UNIX_TIMESTAMP( create_time ) - MOD( UNIX_TIMESTAMP( create_time ) , 60 ) );
How it works :
i) Groups the table by datetime rounded to the interval, 1 minute (60 seconds) here.
ii) Gets the top row from each group.
This can be a good sampling criteria for your data.
This query can be optimized alot on these points:
i) Put a where clause for a date = REQUIRED DATE, and then do other operations on hour+minutes instead of whole datetime.
ii) If your interval is 1 minute, then substring of the timestamp or date_format can be tried too to round it off to nearest minute.
eg.
SELECT create_time
FROM timeTable
WHERE create_time
IN (
SELECT min( create_time )
FROM timeTable
GROUP BY DATE_FORMAT( `create_time` , 'Y-M-D %H:%i' )
);
Try this
SET #time := '1000-01-01 00:00:00';
SET #interval := 60;
SELECT colDate
FROM table
WHERE TIMESTAMPDIFF( SECOND, #time, colDate ) >= #interval
AND #time := colDate
How it works.
#interval is the time difference desired between the current and previous colDate. The first parameter in TIMESTAMPDIFF determines the unit of time that the interval will use. ex: SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, or YEAR.
#time keeps track of the previous colDate, and it is compared with the current row. If the difference between the previous and current colDate is equal to or greater than the interval, it is included.
WHERE timestamp LIKE '%:30:00%' will get you every 30 seconds..
But this will only work if you have uniform entries..if your timestamps dont all end evenly.. you'll need to let us know.
EDIT
I think you may be looking for this:
How do you select every n-th row from mysql

Need to Select DateTime Range in MySQL

I have a txn (transaction) table which has a datetime field named post_ts, which is the field that represents the date of the transaction.
I am writing the code for a batch job (which is supposed to be a weekly job to be run on Sundays) using Spring Batch, and I need to run the query such that I need to fetch all transactions from a week back to the date I am running the job.
Apart from other million business rules to be applied to the query, I need the transactions from (currentdate) to (current date - 7)
You can user mysql DATEDIFF function to achieve this :
SELECT *
FROM txn
WHERE DATEDIFF( CURDATE( ) , `post_ts` ) <= 7;
If you don't need more precision that the date part (no hours, minutes nor seconds to be taken into account), then you can use the function DATEDIFF:
SELECT *
FROM txn
WHERE DATEDIFF( NOW(), post_ts ) <= 7;
EDIT: I've changed the answer. It was mistaken, as I first used the TIMEDIFF function instead of DATEDIFF.
TIMEDIFF gives the difference in hours, minutes, ... whereas DATEDIFF gives the difference in the date part, ignoring the hour:minutes:seconds part.
select
*
from
txn
where
TO_DAYS(NOW()) - TO_DAYS(post_ts) <= 7;

How to compare timestamp dates with date-only parameter in MySQL?

In a SQL statement, how do I compare a date saved as TIMESTAMP with a date in YYYY-MM-DD format?
Ex.: SELECT * FROM table WHERE timestamp = '2012-05-25'
I want this query returns all rows having timestamp in the specified day, but it returns only rows having midnight timestamp.
thanks
You can use the DATE() function to extract the date portion of the timestamp:
SELECT * FROM table
WHERE DATE(timestamp) = '2012-05-25'
Though, if you have an index on the timestamp column, this would be faster because it could utilize an index on the timestamp column if you have one:
SELECT * FROM table
WHERE timestamp BETWEEN '2012-05-25 00:00:00' AND '2012-05-25 23:59:59'
As suggested by some, by using DATE(timestamp) you are applying manipulation to the column and therefore you cannot rely on the index ordering.
However, using BETWEEN would only be reliable if you include the milliseconds. In the example timestamp BETWEEN '2012-05-05 00:00:00' AND '2012-05-05 23:59:59' you exclude records with a timestamp between 2012-05-05 23:59:59.001 and 2012-05-05 23:59:59.999. However, even this method has some problems, because of the datatypes precision. Occasionally 999 milliseconds is rounded up.
The best thing to do is:
SELECT * FROM table
WHERE date>='2012-05-05' AND date<'2012-05-06'
WHERE cast(timestamp as date) = '2012-05-05'
SELECT * FROM table WHERE timestamp >= '2012-05-05 00:00:00'
AND timestamp <= '2012-05-05 23:59:59'
Use a conversion function of MYSQL :
SELECT * FROM table WHERE DATE(timestamp) = '2012-05-05'
This should work
As I was researching this I thought it would be nice to modify the BETWEEN solution to show an example for a particular non-static/string date, but rather a variable date, or today's such as CURRENT_DATE(). This WILL use the index on the log_timestamp column.
SELECT *
FROM some_table
WHERE
log_timestamp
BETWEEN
timestamp(CURRENT_DATE())
AND # Adds 23.9999999 HRS of seconds to the current date
timestamp(DATE_ADD(CURRENT_DATE(), INTERVAL '86399.999999' SECOND_MICROSECOND));
I did the seconds/microseconds to avoid the 12AM case on the next day. However, you could also do `INTERVAL '1 DAY' via comparison operators for a more reader-friendly non-BETWEEN approach:
SELECT *
FROM some_table
WHERE
log_timestamp >= timestamp(CURRENT_DATE()) AND
log_timestamp < timestamp(DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY));
Both of these approaches will use the index and should perform MUCH faster. Both seem to be equally as fast.
SELECT * FROM table WHERE DATE(timestamp) = '2012-05-25'
It will work but not used index on "timestamp" column if you have any because of DATE function. below query used index and give better performance
SELECT * FROM table WHERE timestamp >= '2012-05-05 00:00:00'
AND timestamp <= '2012-05-05 23:59:59'
OR
SELECT * FROM table
WHERE timestamp >= '2012-05-05' AND timestamp < '2012-05-06'
Try running these to check stats
explain SELECT * FROM table
WHERE DATE(timestamp) = '2012-05-25'
explain SELECT * FROM table WHERE timestamp >= '2012-05-05 00:00:00'
AND timestamp <= '2012-05-05 23:59:59'
In case you are using SQL parameters to run the query then this would be helpful
SELECT * FROM table WHERE timestamp between concat(date(?), ' ', '00:00:00') and concat(date(?), ' ', '23:59:59')
When I read your question, I thought your were on Oracle DB until I saw the tag 'MySQL'. Anyway, for people working with Oracle here is the way:
SELECT *
FROM table
where timestamp = to_timestamp('21.08.2017 09:31:57', 'dd-mm-yyyy hh24:mi:ss');
Use
SELECT * FROM table WHERE DATE(2012-05-05 00:00:00) = '2012-05-05'
Let me leave here it may help someone
For people coming from nodejs and expressjs
getDailyIssueOperations(dateName, date, status) {
const queryText = `
select count(*) as total from issues
where date(${dateName})='${date}' and status='${status}';
`;
},
in case date and column name are variables please find the implementation usefull

Retrieve rows less than a day old

I have a column date, which has a default value of CURRENT_TIMESTAMP, eg: 2011-11-16 15:34:02. Is there any way to put a condition in the mysql statement (not in php) to retrieve rows which are less than a day old? Something like:
SELECT * FROM orders where date > 24 hours ago
You can use timestampadd() to get the timestamp for 24 hours ago
SELECT * FROM orders WHERE `date` > timestampadd(hour, -24, now());
This is equivalent to
SELECT * FROM orders WHERE `date` > timestampadd(day, -1, now());
SELECT *
FROM orders
WHERE DATE(`date`) = DATE(NOW() - INTERVAL 1 DAY)
Note the backticks around date, as it's a reserved word.
yup, combine *date_sub* with interval 1 day and curdate() and maybe something else
see documentation here http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-sub
This statement returns all today's rows:
select * from orders where date_field >= CURDATE();
CURDATE() returns today's date, so searches the records starting from midnight.
You can use also the difference directly with timestampdiff function witch is similar to timestampadd.
SELECT * FROM orders WHERE TIMESTAMPDIFF(HOUR, date, NOW()) > 24;
I think this can't as optimized as using timestampadd (because it calculate the difference for each row) but it's, in my opinion, more readable and an alternative if you don't care about optimizing.