22

I have saved the dates of a user's registration as a datetime, so that's for instance 2011-12-06 10:45:36. I have run this query and I expected this item - 2011-12-06 10:45:36 - will be selected:

SELECT `users`.* FROM `users` WHERE created_at >= '2011-12-01' AND
created_at <= '2011-12-06'

But is not. Exist any elegant way, how to select this item? As a first idea that I got was like 2011-12-06 + 1, but this doesn't looks very nice.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
user984621
  • 46,344
  • 73
  • 224
  • 412

8 Answers8

50

Your problem is that the short version of dates uses midnight as the default. So your query is actually:

SELECT users.* FROM users 
WHERE created_at >= '2011-12-01 00:00:00' 
AND created_at <= '2011-12-06 00:00:00'

This is why you aren't seeing the record for 10:45.

Change it to:

SELECT users.* FROM users 
WHERE created_at >= '2011-12-01' 
AND created_at <= '2011-12-07'

You can also use:

SELECT users.* from users 
WHERE created_at >= '2011-12-01' 
AND created_at <= date_add('2011-12-01', INTERVAL 7 DAY)

Which will select all users in the same interval you are looking for.

You might also find the BETWEEN operator more readable:

SELECT users.* from users 
WHERE created_at BETWEEN('2011-12-01', date_add('2011-12-01', INTERVAL 7 DAY));
dash
  • 89,546
  • 4
  • 51
  • 71
  • 2
    If anyone else has problem with the last example, try the following syntax: `SELECT users.* from users WHERE created_at BETWEEN '2011-12-01' AND date_add('2011-12-01', INTERVAL 7 DAY);` – Leia Jan 06 '20 at 22:44
9
SELECT users.* FROM users WHERE created_at BETWEEN '2011-12-01' AND '2011-12-07';
Marek Příhoda
  • 11,108
  • 3
  • 39
  • 53
7

You need to use '2011-12-07' as the end point as a date without a time default to time 00:00:00.

So what you have actually written is interpreted as:

 SELECT users.* 
 FROM   users
 WHERE  created_at >= '2011-12-01 00:00:00' 
   AND  created_at <= '2011-12-06 00:00:00'

And your time stamp is: 2011-12-06 10:45:36 which is not between those points.
Change this too:

 SELECT users.* 
 FROM   users
 WHERE  created_at >= '2011-12-01'  -- Implied 00:00:00
   AND  created_at <  '2011-12-07'  -- Implied 00:00:00 and smaller than 
                                   --                  thus any time on 06
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • +1 I think we posted the same answer at exactly the same time :-) – dash Dec 10 '11 at 17:19
  • @dash Actually Loki posted it half a minute earlier and his was supposed to be the accepted answer, but you were luckier. +1 for him for the faster answer, and +1 for you for giving him +1. – Racil Hilan Mar 24 '14 at 14:19
4

Another alternative is to use DATE() function on the left hand operand as shown below

SELECT users.* FROM users WHERE DATE(created_at) BETWEEN '2011-12-01' AND '2011-12-06'

 

manotheshark
  • 4,297
  • 17
  • 30
1

Have you tried before and after rather than >= and <=? Also, is this a date or a timestamp?

vextorspace
  • 934
  • 2
  • 10
  • 25
  • my bad, before and after are from something else. for a timestamp you need to add a time as well as date as others have answered. – vextorspace Dec 10 '11 at 17:23
1

Searching for created_at <= '2011-12-06' will search for any records that where created at or before midnight on 2011-12-06 . You want to search for created_at < '2011-12-07'.

Nawin
  • 1,653
  • 2
  • 14
  • 23
Brian Hoover
  • 7,861
  • 2
  • 28
  • 41
0

You can use MySQL DATE function like below

For instance, if you want results between 2017-09-05 till 2017-09-09

SELECT DATE(timestamp_field) as date FROM stocks_annc WHERE DATE(timestamp_field) >= '2017-09-05' AND DATE(timestamp_field) <= '2017-09-09'

Make sure to wrap the dates within single quotation ''

Edit: A better solution would be this. It would make sure that it uses the index if any exists.

select date(timestamp_field) as date from stocks_annc where time_stamp_field >= '2022-01-01 00:00:00' and time_stamp_field <= '2022-01-10 00:00:00'

Hope this helps.

Koushik Das
  • 9,678
  • 3
  • 51
  • 50
0

Maybe use in between better. It worked for me to get range then filter it

sys_debug
  • 3,883
  • 17
  • 67
  • 98