Selecting MySQL datetime columns which are 0000-00-00 00:00:00 - mysql

I'm looking for a simple way to select datetime columns which are 000-00-00 00:00:00 (basically the default unset value).
The following query seems to be working:
SELECT * FROM myTable WHERE datetimeCol < 1
But will this reliably work all the time and across different mysql versions?

I would check for "zero" dates like this:
SELECT * FROM myTable WHERE datetimeCol = CONVERT(0,DATETIME)
I would prefer the equality predicate over an inequality predicate; it seems to convey my intentions more clearly. And if there are more predicates in the statement, and if the datetimeCol is a leading column in an index, it may help the optimizer make use of a multi-column index.

Try this:
SELECT * FROM myTable WHERE datetimeCol = '0000-00-00 00:00:00'
Might seem obvious in hindsight ;)

What about comparing to 0 value:
datetimeCol = 0

Try this:
SELECT * FROM myTable WHERE UNIX_TIMESTAMP(datetimeCol) = 0

Related

Query data between the same date

Is it possible to do something like this?
select * from table where Date BETWEEN '2019-05-29' AND '2019-05-29'
Yes it is possible. If you have time part you could use DATE function to skip it:
SELECT * FROM table WHERE DATE(Date) BETWEEN '2019-05-29' AND '2019-05-29'
-- it may degrade performance, condition is not SARGable
Yes, but the better approach is:
select t.*
from table t
where t.Date >= date('2019-05-29') AND
t.Date < date('2019-05-29') + interval 1 day
Why is this better? It doesn't have a function on the column name, so it can make use of an index on the date column.
Yes you can, if you want to run it in a test window without manually changing the date within the code you can set it as a variable. Use trunc to get rid of time i.e there will be no 29-05-2019 23:59:00. If you want the same date within a time period remove the trunc and then you can set hours-minutes-seconds which makes your query more precise
SELECT t.*
FROM table t
WHERE t.date BETWEEN trunc(to_date(:datefrom, 'dd.mm.yyyy hh24:mi:ss')) AND
trunc(to_date(:dateto, 'dd.mm.yyyy hh24:mi:ss'))

Query huge table fast based on timezone

I need to query a table that has 1,852,789,683 rows which is 179.3GB in size in the fastest way possible. My conditions are it needs to be a whole day (24hrs) Japan time.
Query:
SELECT COUNT(*) CNT
FROM info_table
WHERE DATE(CONVERT_TZ(created_at, '+00:00', '+09:00')) = 20141216;
I have left it running for almost an hour now but it's still not done. Any advice?
DESCRIBE:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE info_table ALL NULL NULL NULL NULL 1793315059 Using where
Your query is going to evaluate that function on the created_at column for every flipping row in the table; that's a full scan.
To enable MySQL to do an efficient range scan operation on an index, you need to reference the bare column in the predicate, and you need an index with a leading column of created_at, and the query needs to be of the form:
WHERE created_at >= val1
AND created_at < val2
The trick will be developing val1 and val2, the expressions that return the upper and lower bounds for the timestamp.
if we know:
DATE(CONVERT_TZ(created_at, '+00:00', '+09:00')) = 20141216
then we know:
CONVERT_TZ(created_at, '+00:00', '+09:00')) >= '2014-12-16'
AND CONVERT_TZ(created_at, '+00:00', '+09:00')) < '2014-12-17'
and (maybe?)...
created_at >= CONVERT_TZ('2014-12-16','+09:00','+00:00')
AND created_at < CONVERT_TZ('2014-12-17','+09:00','+00:00')
I'm not sure about the behavior if the CONVERT_TZ function, whether the inversion is equivalent for all values in your case. Again, the "trick" will be getting the expressions that return the upper and lower bounds of your timestamp.
In our environment, we use GMT for all date, datetime and timestamp in the database; we use GMT for the database connections. The application layer does the appropriate timezone conversions. When I have a need to do something like you're doing, I'd be inclined to write something like this:
created_at >= '2014-12-16' + INTERVAL -9 HOUR
AND created_at < '2014-12-16' + INTERVAL 24-9 HOUR
You should create the statement so that it takes advantage of an index and then create the index if you need to run this often. With a table so large it may take some time to create the index. To use and index you can rewrite the statement as:
select count(*) cnt
from info_table
where created_at >= '2014-12-16' and created_at< '2014-12-17'
Even without and index the above may run a bit faster.
The issues is that you are converting each row-value before it gets checked. Change that to the other side
SELECT COUNT(*) CNT
FROM info_table
WHERE created_at = YourConvertedTimeZoneDateValue

SQL - Select all rows which is >= and <=

i trying to do a sql query which i combine de compare operators with substring.
in my column date i have the following value inside : 09-01-2014 12:02:55
what i try to now is to select all rows which is >= 09-01-2014 and for example <=22-01-2014
how can i do it?
i have trying for example with this code:
SELECT * From table Where Name= 'Something'
AND SUBSTRING(date,1,10) = '09-01-2014'
AND SUBSTRING(date,1,10) < '22-01-2014'
You can use the BETWEEN operator
SELECT * FROM table
WHERE Name = 'Something'
AND SUBSTRING(date, 1, 10) BETWEEN '09-01-2014' AND '22-01-2014'
EDIT: I'm still leaving this here, but it is not an error proof solution (as pointed out by oerkelens down in the comments)
The BETWEEN operator will work, like this:
SELECT *
From table
Where Name= 'Something'
AND `date` BETWEEN '2014-01-09' AND '2014-01-23'
Working Demo: http://sqlfiddle.com/#!2/b4d7e
Try this:
SELECT *
FROM tableA a
WHERE a.nme= 'Something' AND
DATE(STR_TO_DATE(a.date, '%d-%m-%Y %H:%i:%s')) >= '2014-01-09' AND
DATE(STR_TO_DATE(a.date, '%d-%m-%Y %H:%i:%s')) <= '2014-01-22';
OR
SELECT *
FROM tableA a
WHERE a.nme= 'Something' AND
DATE(STR_TO_DATE(a.date, '%d-%m-%Y %H:%i:%s')) BETWEEN '2014-01-09' AND '2014-01-22';
Using the following syntax makes your query sargable. It allows query to use any Indexes defined on the date column. for more information SARGable Queries with Datetime Datatype
SELECT * From table
Where Name= 'Something'
AND [DateColumn] >= '20140109'
AND [DateColumn] <= '20140122'
You are converting the date from the table row into a string before comparing to the bookend dates. You need to do the opposite. Convert the bookend dates from strings to dates, then compare each test date.
Some form of the CONVERT or CAST function should do that for you.
The reason your approach won't work is that when SQL server compares strings, it uses alphabetical order. You want ascending date order, which is a different order.
Which Database do you use? Oracle:
SELECT *
FROM table tbl
WHERE 1=1
AND name = 'Something'
AND trim(tbl.column) >= to_date('2014-01-09','DD-MM-YYYY')
AND trim(tbl.column) <= to_date('2014-01-22','DD-MM-YYYY')
or you just convert it into a number/integer like YYYYMMDD then the >= =< operators will work too.

How to use greater than operator with date?

No idea what is going on here. Here is the query, right from phpMyAdmin:
SELECT * FROM `la_schedule` WHERE 'start_date' >'2012-11-18';
But I consistently get all records in the table returned, including those with start date 2012-11-01. What gives?
you have enlosed start_date with single quote causing it to become string, use backtick instead
SELECT * FROM `la_schedule` WHERE `start_date` > '2012-11-18';
SQLFiddle Demo
In your statement, you are comparing a string called start_date with the time.
If start_date is a column, it should either be
SELECT * FROM `la_schedule` WHERE start_date >'2012-11-18';
(no apostrophe)
or
SELECT * FROM `la_schedule` WHERE `start_date` >'2012-11-18';
(with backticks).
Hope this helps.
Try this.
SELECT * FROM la_schedule WHERE `start_date` > '2012-11-18';
I have tried but above not working after research found below the solution.
SELECT * FROM my_table where DATE(start_date) > '2011-01-01';
Ref
Adding this since this was not mentioned.
SELECT * FROM `la_schedule` WHERE date(start_date) > date('2012-11-18');
Because that's what actually works for me. Adding date() function on both comparison values.
In my case my column was a datetime it kept giving me all records. What I did is to include time, see below example
SELECT * FROM my_table where start_date > '2011-01-01 01:01:01';
If you are comparing timestamp - you could try following
select * from table where columnInTimestamp > ((UNIX_TIMESTAMP() * 1000) - (1*24*60*60*1000))
Here UNIX_TIMESTAMP()gives current timestamp where as "12460601000" is the timestamp for 1 day -- With this you can find data just got created in 1 day or 2 days etc.

mysql using a DateTime in the whereclause

I tried this query below but it still returns days that had -1 values. I want the where clause to return rows that are 2 days or newer. Thanks!
SELECT uniqueKey,(TO_DAYS(TimeStampColumn) - TO_Days(Now())) as 'dayDiff'
FROM couponextractor.tblresults
where 'dayDiff' >= 0
Because you just compare string 'daydiff' >= 0, which always evaluates to 0 => true
You need to get rid of quotes and use HAVING, beside that's very inefficient query... it's better to compute the date before and just use >= operator on the column.
HAVING dayDiff >= 0
So just compute the exact date, and then just do
WHERE TimeStampColumn >= "XXXX-XX-XX AA:AA:AA" so it can be optimized by the server if you have indexes.
SELECT * FROM tbl WHERE datetime < NOW() - INTERVAL 2 DAY
Why don't you use the MYSQL DATEDIFF- Function?
SELECT uniqueKey,DATEDIFF(TimeStampColumn,Now()) as 'dayDiff'
FROM couponextractor.tblresults
where DATEDIFF(TimeStampColumn,Now()) >= 1
Think this will do the job. Perhaps you have to cast the TimeStampColumn.