I cant seem to get this to work, It returns Null
SELECT sdt, timeFor, DATE_ADD(TIMESTAMP(sdt), INTERVAL timeFor MINUTE) FROM tbl_day
The return keeps returning
sdt, timeFor, DATE_ADD(TIMESTAMP(sdt), INTERVAL timeFor MINUTE)
'0000-00-00 01:00:00', 15, ''
Columns Type
sdt DATETIME
timeFor BIGINT(20)
Any ideas
MySQL usually returns NULL on date/time operations when column value is incomplete datetime. Something like 2010-00-05 11:22:33, etc. Also using timestamp function on sdt column might not be a good idea. I'd suggest providing normal datetime value.
Related
The table I'm querying from has this DateTime column.
created_time
2022-03-19T15:21:52+08:00
2022-03-19T13:10:22+08:00
2022-03-19T13:09:52+08:00
2022-03-19T13:02:47+08:00
2022-03-20T20:51:03+08:00
select extract(year_month from curtime())
Using extract (as above) doesn't work as it will get me: 202203.
SELECT created_time
FROM `freemark-prod-zohocrm`.patients p
where select extract(year_month from curtime())
Therefore the query above will not give me any result as my 'where' clause needs to specifically ask for '2022-03%' and not 202203.
SELECT created_time
FROM `freemark-prod-zohocrm`.patients p
where date_format(p.created_time, '%Y')=(select extract(year from curtime()))
and date_format(p.created_time, '%m')=(select extract(month from curtime()))
Therefore I am currently using the query above to obtain Year='2022' AND Month='03' which I feel doesn't look that nice and might cause me future problems.
I am wondering if there is a more elegant way to get the current 'Year-Month' (eg.'2022-03%') to use in my 'where' clause.
Thank you for your time.
LIKE Example db<>fiddle
Since the query is a simple YYYY-MM prefixed lookup, use LIKE DATE_FORMAT(NOW(), '%Y-%m-%%') as 2022-03-%. Functioning the same for either DATETIME or VARCHAR column data-types, and is by-far the fastest solution regardless of indexing.
SELECT p.created_time
FROM `freemark-prod-zohocrm`.patients p
WHERE p.created_time LIKE DATE_FORMAT(NOW(), '%Y-%m-%%');
Compare YEAR_MONTH Criteria db<>fiddle
To fix the issue with the original query not returning results, match the criteria column and value functions. However, as a function is called on the column value a full-table scan will be performed.
SELECT p.created_time
FROM `freemark-prod-zohocrm`.patients p
WHERE EXTRACT(YEAR_MONTH FROM p.created_time) = EXTRACT(YEAR_MONTH FROM NOW());
To prevent a full-table scan avoid altering column values in the criteria using DATE_FORMAT(created_time), EXTRACT(... FROM created_time) or other functions, which will cause MySQL to check all rows in the table to determine if the condition matches.
MySQL 5.5 and earlier db<>fiddle
Note: In MySQL 5.5 and earlier, extract(year_month from curtime()) or for any date specific Temporal Intervals will return NULL because curtime() returns the TIME portion as HH:MM:SS.The behavior appears to have changed in MySQL 5.6 and later, where EXTRACT() will apply to the current date when the date argument is supplied as a TIME data-type and failing when supplied as a time string literal.
However, an undesirable value will be returned when using a date + time interval such as DAY_MINUTE and the date portion of the value is omitted.
SELECT
curtime(), /* 19:07:40 */
extract(year_month from curtime()), /* NULL */
extract(day_minute from curtime()); /* 1907 */
To resolve the issue always use NOW(), otherwise in MySQL 5.5 and earlier curtime() should be replaced with CURDATE() or NOW() depending on the interval being used.
DATE Interpreted Example db<>fiddle
As DATE_FORMAT() returns a string literal, to prevent string comparison issues in MySQL such as '10' > '2' = false, enforce a DATE or DATETIME context.
When using DATE or DATETIME interpreted values (see explanation below) to retrieve the rows for an entire month, the following criteria values can be used to force the condition to process in the context of a DATE data-type
DATE(DATE_FORMAT(NOW(), '%Y-%m-01')) to get the first day of the current month as a DATE data-type
LAST_DAY(NOW()) + INTERVAL 1 DAY to get the the first day of the next month as a DATE data-type.
SELECT p.created_time
FROM `freemark-prod-zohocrm`.patients p
WHERE p.created_time >= DATE(DATE_FORMAT(NOW() ,'%Y-%m-01'))
AND p.created_time < LAST_DAY(NOW()) + INTERVAL 1 DAY;
LAST_DAY(NOW()) will return the date as 2022-03-31
+ INTERVAL 1 DAY will increment the date by one day to 2022-04-01
MySQL 5.6+ Results
CREATE TABLE patients_varchar (
`id` INTEGER NOT NULL PRIMARY KEY,
`created_time` VARCHAR(25),
INDEX(`created_time`)
);
INSERT INTO patients_varchar
(`id`, `created_time`)
VALUES
('1', '2022-02-19T15:21:52+08:00'), /* Added to verify range */
('2', '2022-03-19T15:21:52+08:00'),
('3', '2022-03-19T13:10:22+08:00'),
('4', '2022-03-19T13:09:52+08:00'),
('5', '2022-03-19T13:02:47+08:00'),
('6', '2022-03-20T20:51:03+08:00'),
('7', '2022-03-31T20:51:03+08:00'),
('8', '2022-04-20T20:51:03+08:00'); /* Added to verify range */
created_time
2022-03-19T13:02:47+08:00
2022-03-19T13:09:52+08:00
2022-03-19T13:10:22+08:00
2022-03-19T15:21:52+08:00
2022-03-20T20:51:03+08:00
2022-03-31T20:51:03+08:00
VARCHAR and Date Time Literals Explanation
When the column data-type is VARCHAR using a valid date time string literal format such as YYYY-MM-DDTHH:MM:SS+08:00, MySQL will automatically interpret the column value format of YYYY-MM-DDTHH:MM:SS+MM:HH as a DATETIME data-type appropriately when provided a criteria value in the DATE or DATETIME data-type context.Please see the String and Numeric Literals in Date and Time Context for more details.
DATETIME context and time zone offsets
For MySQL 5.6+ to specify the inclusion of a time value, use TIMESTAMP(DATE_FORMAT(LAST_DAY(NOW()), '%Y-%m-%d 23:59:59')) to force a DATETIME context as opposed to using DATE().
For MySQL 5.5 and earlier db<>fiddle, when specifying a DATETIME context, the time zone offset in the column value is not parsed correctly and produces a different result. Using a string context of DATE_FORMAT(LAST_DAY(NOW()), '%Y-%m-%dT23:59:59') resolves the issue but may produce unexpected results, due to the string context comparison eg: '10' > '2' = false.
Note: the T is required for MySQL to parse the YYYY-MM-DDTHH:MM:SS formatted column value correctly.
For example the following conditions will all return true due to the DATETIME context. While MySQL 8.0+ will process the time zone offset when it is included in the string.
SELECT
'2022-02-19T15:21:52+08:00' = TIMESTAMP('2022-02-19T15:21:52'),
'2022-02-19T15:21:52+08:00' < TIMESTAMP('2022-02-20T15:21:52'),
'2022-02-19T15:21:52+08:00' > TIMESTAMP('2022-02-18T15:21:52'),
'2022-02-19T00:00:00+08:00' = TIMESTAMP('2022-02-19'),
'2022-02-19T15:21:52+08:00' < TIMESTAMP('2022-02-20'),
'2022-02-19T15:21:52+08:00' > TIMESTAMP('2022-02-18');
As opposed to the following conditions comparing strings that all return unexpected results.
SELECT
'2022-02-19T15:21:52+08:00' = '2022-02-19T15:21:52', # false
'2022-02-19T15:21:52+08:00' <= '2022-02-19T15:21:52', # false
'2022-02-19T15:21:52+08:00' > '2022-02-19T15:21:52'; # true
querying based on function calls such as extract(), or others datepart(), etc. are not Sargeable
What you would be better doing is something like
where
created_time >= '2022-03-01'
AND created_time < '2022-04-01'
This way, it gets the entire month in question including time portion up to 2022-03-31 # 11:59:59pm.
Now, to compare automatically against whatever the current date IS, you can do with MySQL Variables to compute the first of the month and beginning of next month for your from/to range.
select
...
from
( select #FirstOfMonth := DATE_FORMAT(CURDATE(), '%Y-%m-01'),
#FirstOfNextMonth := date_add( #FirstOfMonth, interval 1 month )) sqlvars,
`freemark-prod-zohocrm`.patients p
where
p.created_time >= #FirstOfMonth
AND p.created_time < #FirstOfNextMonth
Here is my table "tb_posts":
I want to select only those rows where datetime field i.e. post_date_published is not equal to 0000-00-00 00:00:00. I am using following query but it doesn't work:
SELECT * FROM `tb_posts` WHERE `post_date_published` IS NOT NULL
I am getting the same output as shown in the above picture.
Why IS NOT NULL is not working?
As per the MYSQL documentation it saves invalid dates as '0000-00-00 00:00:00'. It will not be considered as NULL.
Try comparing with the date '0000-00-00 00:00:00':
SELECT * FROM tb_posts where post_date_published != '0000-00-00 00:00:00'
A method I use with this sort of thing is
SELECT `columns` FROM `tb_posts` WHERE UNIX_TIMESTAMP(`post_date_published`) > 0
From the MySQL Documentation:
The valid range of argument values is the same as for the TIMESTAMP
data type: '1970-01-01 00:00:01.000000' UTC to '2038-01-19
03:14:07.999999' UTC. If you pass an out-of-range date to
UNIX_TIMESTAMP(), it returns 0.
The UNIX_TIMESTAMP function forces the result to be an integer so it's much easier to work with in these quick comparisons. It is also vital for working with MySQL 5.7 where "empty" (ie zero value) date/time columns are not allowed.
(I had a lot of grief trying to convert various date columns to NULL because MySQL 5.7+ didn't recognise 0000-00-00 00:00:00 as a valid comparison -- so I converted it to a unix timestamp so as to compare the timestamp rather than the actual [invalid] date.)
i looking for some help about MySQL, Very easy question, but really breaked my brain for some time.
i have a table called "logs", That have "date" thing, That is INT(11) of Timestamp, So, it use timestamp actual for it.
i gonna make a script that execute a SQL command each minute, That Check ALL rows, if "date" have more/equal than 6 hours, i tired so much, and nothing for help.
Some commands i used and won't worked.
DELETE FROM logs WHERE date < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 6 HOUR));
DELETE FROM logs WHERE date < NOW() - INTERVAL 6 HOUR;
Won't help, So, i asking here if you can help me, Thanks.
You can do something like that :
DELETE FROM logs
WHERE FROM_UNIXTIME(date) < UNIX_TIMESTAMP(NOW() - INTERVAL 6 HOUR);
The date "thing" is called a column. The column has a specific datatype. The question indicates that the column is datatype INT(11). And in that column is stored unix-style 32-bit integer number of seconds since 1970-01-01 UTC.
If that's all true, then the first query form is appropriate. The expression on the right side (of the less than comparison) returns an integer number of seconds.
As a demonstration, consider this expression:
SELECT UNIX_TIMESTAMP( NOW() + INTERVAL -6 HOUR ) ==> 1528450555
or, the way the original is written
SELECT UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 6 HOUR))
returns an equivalent result.
The second query can be evaluated, but the automatic conversion from DATETIME to numeric will return us an integer value like 20180608153555 (i.e. yyyymmddhhmmss), not number of seconds since the beginning of the epoch.
Consider a demonstration, DATETIME dataytpe evaluated in numeric context:
SELECT NOW() + INTERVAL -6 HOUR + 0 ==> 20180608153600
If we use that expression, compare that to an INT(11) column, and delete all rows that have an INT(11) column less than that value, it's going to delete every row in the table that has a non-NULL value in that column.
Your date column must be of Type TIMESTAMP and not INT in order to be able compare timestamps with each other properly, or you can write:
DELETE FROM logs WHERE FROM_UNIXTIME(date) < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 6 HOUR));
I am looking for a solution to find with mySQL every result that was created since a(or many) entire week(s) (7 days).
I tried this but it seems sometimes the result is false because is there more than one result per week.
SELECT *
FROM `datatable`
WHERE MOD(TIMESTAMPDIFF(DAY,UNIX_TIMESTAMP(created),NOW()),7)=0;
created is a timestamp.
Thanks for any response!
Try this:
SELECT
*
FROM
`datatable`
WHERE 1
AND `created` >= DATE_FORMAT(NOW() - INTERVAL 7 DAY,'%Y-%m-%d 00:00:00')
AND `created` <= DATE_FORMAT(NOW() - INTERVAL 7 DAY,'%Y-%m-%d 23:59:59')
UNIX_TIMESTAMP(), UNIX_TIMESTAMP(date)
If called with no argument, returns a Unix timestamp (seconds since
'1970-01-01 00:00:00' UTC) as an unsigned integer. If UNIX_TIMESTAMP()
is called with a date argument, it returns the value of the argument as
seconds since '1970-01-01 00:00:00' UTC, date may be a DATE string, a
DATETIME string, a TIMESTAMP, or a number in the format YYMMDD or
YYYYMMDD. The server interprets date as a value in the current time
zone and converts it to an internal value in UTC. Clients can set their
time zone as described in
http://dev.mysql.com/doc/refman/5.1/en/time-zone-support.html.
So, do not use UNIX_TIMESTAMP() function, but simple DATE().
As far as I can understand the question, you want the records that are are newer than a certainDate, AND not older than 7 days, or 14 days,..., 140 days (whichever of them is closest to the certainDate) from current date.
IF I understand you correctly, following might work for you with certainDate = '2013-04-01 00:00:00'
SELECT *
FROM `datatable`
WHERE `created` >= ADDDATE(
'2013-04-01 00:00:00',
INTERVAL MOD(ABS(TIMESTAMPDIFF(DAY, NOW(), '2013-04-01 00:00:00')),7) DAY
)
This query will fetch all results having created in last 14 days.
Below is the CREATE TABLE statement used to create my table:
CREATE TABLE IF NOT EXISTS `data_received` (
`id` int(10) unsigned NOT NULL,
`edit_time` datetime NOT NULL}
Below is how data is saved in table if 'edit_time' value is not provided:
id edit_time
1 0000-00-00 00:00:00
Now, if I execute the following statement:
SELECT TIMESTAMPDIFF( HOUR , edit_time, NOW( ) ) AS diff_in_hours
FROM data_received;
I get result: NULL
Can someone please help me understand what is happening?
That is because 0000-00-00 00:00:00 is not a valid DATETIME expression accepted by the function.
Please check documentation.
Use this method to keep edit-time in mysql
`edit_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Auto-update time'
Mysql tends to insert rubbish in an attempt to be "helpful". Best to tell it not to do that by settings mysql to STRICT mode so it behaves more like a database should.
SET sql_mode='STRICT_ALL_TABLES'
For details please read the manual.
0000-00-00 00:00:00 will probably interpreted as null. And comparing null in a TIMESTAMPDIFF will lead to null result.
MySQL doc says
In MySQL, the zero date is defined as '0000-00-00', even though this date is itself considered invalid.
There is no zeroth of zero in year zero, so you cannot calculate the time since then:
SELECT TIMESTAMPDIFF(HOUR, '0000-00-00 00:00:00', NOW())
NULL
Apparently MySQL does not have a problem with year 0 itself, as this returns a result:
SELECT TIMESTAMPDIFF(HOUR, '0000-01-01 00:00:00', NOW())
17643758