Date comparison in query: Correct logic but wrong result - mysql

I have this very simple query. But it's returning wrong result.
select * from `table_a` where date(`schedule`) > '2021-11-13 06:31:00'
In my table, I have these rows
table_a
+---------------------+
| schedule |
+---------------------+
| 2021-11-13 08:59:00 |
+---------------------+
| 2021-11-13 08:59:00 |
+---------------------+
| 2021-11-13 08:59:00 |
+---------------------+
Technically, this query should return all rows. But 0 rows is returned.
I tried changing the operation to <and it returned all rows (which is the opposite) . Did I miss something here?
note: schedule datatype is DATETIME.

Your schedule column is datetime, with a time component, so remove the cast to date:
SELECT * FROM table_a WHERE schedule > '2021-11-13 06:31:00';
What was happening is that your 3 records were all being casted to 2021-11-13 at midnight, which is the same as 2021-11-13 00:00:00. It should be clear that all of the 3 records occurred past midnight on this date.

Related

Something curious is happening subtracting dates in a query - 70 days appears from nowhere :-/ [duplicate]

the leetcode question 197.Rising Temperature
Given a Weather table, write a SQL query to find all dates' Ids with higher temperature compared to its previous (yesterday's) dates.
+---------+------------------+------------------+
| Id(INT) | RecordDate(DATE) | Temperature(INT) |
+---------+------------------+------------------+
| 1 | 2015-01-01 | 10 |
| 2 | 2015-01-02 | 25 |
| 3 | 2015-01-03 | 20 |
| 4 | 2015-01-04 | 30 |
+---------+------------------+------------------+
For example, return the following Ids for the above Weather table:
+----+
| Id |
+----+
| 2 |
| 4 |
+----+
i didn't know the function DATEDIFF(),so i wrote my sql solution:
select w1.Id
from Weather w1,Weather w2
where w1.RecordDate - w2.RecordDate = 1
and w1.Temperature > w2.Temperature
and i went through the testcase but got a wrong submit,the right solution is use funtion DATEDIFF()
select w1.Id
from Weather w1,Weather w2
where DATEDIFF(w1.RecordDate,w2.RecordDate)=1
and w1.Temperature > w2.Temperature
so my question is what's the difference between
DATEDIFF(w1.RecordDate,w2.RecordDate)=1and w1.RecordDate - w2.RecordDate = 1
thank you for your help
If the datatype of RecordDate is DATETIME rather than DATE, subtracting them returns a large value that contains the difference between the times as well as the dates. E.g.
mysql> select cast('2019-03-21 10:20:30' as datetime) - cast('2019-03-11 9:15:20' as datetime) as difference;
+-----------------+
| difference |
+-----------------+
| 10010510.000000 |
+-----------------+
But if they're DATE then subtraction should be the same as DATEDIFF():
mysql> select cast('2019-03-21' as date) - cast('2019-03-11' as date) as difference;
+------------+
| difference |
+------------+
| 10 |
+------------+
When we do simple addition and subtraction on the date or datetime, it will convert it into a number and after that the actual operation will execute. After the operation execution, the output will not be the date datatype.
For example,
For addition (+) : -
'2020-07-31' + 1 => 20200732
For subtraction (-) : -
'2020-08-01' - '2020-07-31' => 70
It should return 1 but as they consider it as a number so they return 70 instead of 1.
This is the reason we cannot apply direct addition or subtraction on date.
To get the actual difference between two dates one should must use the DateDiff().
Datediff(cast('2020-08-01' as Date),Cast('2020-07-31' as Date)) => 1

Mysql: Execute query for each date

I am using Mysql 5.5.43-0+deb7u1.
I have managed to create this query to fetch rain data for particular day (I use MODbecause rain data is updated at every full hour while other data gets update more frequently.)
SELECT date,SUM(rainmm) FROM weather WHERE MOD(minute(time),60)=0 AND date=CURDATE()-1;
+------------+-------------+
| date | sum(rainmm) |
+------------+-------------+
| 2015-06-23 | 0.1 |
+------------+-------------+
1 row in set (0.15 sec)
I am looking for a way to get results for all days with single query instead of needing to check every day manually. I am unsure if I should use loops and iterate number for days from current date or if there is better way to accomplish this.
Desired result:
SELECT date, [Smart query to get all days at once]
+------------+-------------+
| date | sum(rainmm) |
+------------+-------------+
| 2015-06-23 | 0.1 |
| 2015-06-24 | 0.0 |
| ... | ... |
| 2015-11-11 | 11.1 |
+------------+-------------+
Does this do what you want
SELECT date,SUM(rainmm) FROM weather WHERE MOD(minute(time),60)=0
GROUP BY date
ORDER BY date;

MySQL select Current_timestamp between

I have a list of users in MySQL and on subscription the timestamp is set in the data base using the CURRENT_TIMESTAMP.
Now I want to do a select from this table where the subscribe date is between day X and day Y
I tried several queries but somehow they all turn up empty.
Here is my last version
SELECT *
FROM users
WHERE subscribe_date BETWEEN '2013-10-07'AND '2013-13-10'
As I know for sure this date: 2013-10-08 14:38:49
is in the subscribe_data field It should turn up somehow
What is the best way to do this?
Maybe good to know my 'subscribe_date' column has type 'timestamp' and is auto filled with 'CURRENT_TIMESTAMP'
Here is the data in this table:
+----+-----------+---------------------+
| id | firstname | subscribe_date |
+----+-----------+---------------------+
| 20 | Peter | 2013-10-01 14:37:17 |
| 21 | Jack | 2013-10-08 14:38:49 |
| 22 | Andrew | 2013-10-10 14:41:03 |
| 23 | Margret | 2013-10-14 14:42:46 |
+----+-----------+---------------------+
Since TIMESTAMP is up to seconds precision usually, you have to add time part:
SELECT *
FROM users
WHERE (subscribe_date BETWEEN '2013-10-07 00:00:00' AND '2013-12-10 23:59:59')
I've fixed your '2013-13-10' to '2013-12-10 23:59:59' since there's no 13-th month (and in DATETIME format it's YYYY-MM-DD, so month goes second)

Mysql parse dates in this format: 2012-03-27T03:03:00?

I have a table which stores times as a simple varchar, in a format that looks like "2012-03-27T03:03:00".
I'd like to use mysql's date functions with this data. Some functions work fine, i.e.
mysql> select year('2012-03-14T11:28:32'), month('2012-03-14T11:28:32');
+-----------------------------+------------------------------+
| year('2012-03-14T11:28:32') | month('2012-03-14T11:28:32') |
+-----------------------------+------------------------------+
| 2012 | 3 |
+-----------------------------+------------------------------+
1 row in set (0.00 sec)
But hour and minute functions fail:
mysql> select hour('2012-03-14T11:28:32'), minute('2012-03-14T11:28:32');
+-----------------------------+-------------------------------+
| hour('2012-03-14T11:28:32') | minute('2012-03-14T11:28:32') |
+-----------------------------+-------------------------------+
| 0 | 20 |
+-----------------------------+-------------------------------+
1 row in set, 2 warnings (0.00 sec)
I believe it is the 'T' in my date format that screws up mysql. If I manually replace it with a space, the functions work:
mysql> select hour('2012-03-14 11:28:32'), minute('2012-03-14 11:28:32');
+-----------------------------+-------------------------------+
| hour('2012-03-14 11:28:32') | minute('2012-03-14 11:28:32') |
+-----------------------------+-------------------------------+
| 11 | 28 |
+-----------------------------+-------------------------------+
1 row in set (0.00 sec)
Is there some simple way I can tell mysql to parse the 'T'???
Those MySQL Date and Time functions (HOUR, for example) require a specific part of the timestamp.
Therefore, you need to use TIME and DATE to extract the time and date, respectively, from the passed timestamp:
Extracting the time:
select hour(time('2012-03-14T11:28:32')), minute(time('2012-03-14T11:28:32'));
Extracting the date:
select year(date('2012-03-14T11:28:32')), month(date('2012-03-14T11:28:32'));
SELECT HOUR(STR_TO_DATE('2012-03-14T11:28:32','%Y-%m-%dT%k:%i:%s'))
STR_TO_DATE is pretty good about returning NULL for rubbish dates like this non-leap-year item.
SELECT STR_TO_DATE('2011-02-29T11:28:32','%Y-%m-%dT%k:%i:%s')
It also lets you do stuff like
SELECT STR_TO_DATE('2011-02-28T11:28:32','%Y-%m-%dT%k:%i:%s') + INTERVAL 1 QUARTER
or
SELECT STR_TO_DATE('2011-02-28T11:28:32','%Y-%m-%dT%k:%i:%s') - INTERVAL 35 MINUTE
and have everything work right.
See here for the conversion specifiers.
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format

Failed mysql date query

I want to delete rows from a table that has a column more than 7200 secs old.
The Query
mysql_query("delete from logged where DATE_ADD ( log, INTERVAL $this->loginDuration SECOND) < NOW()",$this->link);
where:
name of table = logged;
name of column = log;
$this->loginDuration = 7200;
The value of log in db: 2011-06-25 09:56:51.
Todays date and time [ Now() ] : 2011-07-05 11:39:02
The query is meant to delete the row with log value 2011-06-25 09:56:51 because it is older than 7200 seconds but it does not.
What am I not getting right?
You have a space between DATE_ADD and the parenthesis: ( log, ....
Use DATE_ADD( log, ...
From MySQL docs, Functions and Operators :
Note
By default, there must be no
whitespace between a function name and
the parenthesis following it. This
helps the MySQL parser distinguish
between function calls and references
to tables or columns that happen to
have the same name as a function.
However, spaces around function
arguments are permitted.
And:
You can tell the MySQL server to
accept spaces after function names by
starting it with the
--sql-mode=IGNORE_SPACE option. (See Section 5.1.6, “Server SQL Modes”.)
Individual client programs can request
this behavior by using the
CLIENT_IGNORE_SPACE option for
mysql_real_connect(). In either case,
all function names become reserved
words.
I wanted to show you what I did (could not post this as a comment)
+----------------------+
| temp.d(table.column) |
+----------------------+
| 2011-07-05 22:08:20 |
| 2011-07-05 22:08:20 |
| 2011-07-05 22:08:21 |
| 2011-07-05 22:08:21 |
| 2011-07-05 22:08:22 |
| 2011-07-05 22:08:22 |
| 2011-07-05 22:08:23 |
| 2011-07-05 22:08:23 |
| 2011-07-05 22:08:24 |
| 2011-07-05 22:08:24 |
+----------------------+
10 rows in set (0.00 sec)
mysql> delete from temp where DATE_ADD(d, INTERVAL 1 SECOND) < NOW();
Query OK, 10 rows affected (0.01 sec)