In my database table I have a field for date (varchar field to save date in yy-mm-dd format ), now I want to select records for two weeks ago.
How can i do it ?
Implicit date arithmetic is fairly flexible in MySQL. You can compare dates as strings without explicit use of CAST() or DATE(), but you're trusting MySQL to interpret your format correctly. Luckily for you, it will do just fine with yy-mm-dd.
I would recommend using BETWEEN and INTERVAL so that your query is easily readable; for example:
SELECT * FROM Holidays
WHERE Date BETWEEN (NOW() - INTERVAL 14 DAY) AND NOW();
The only trick with BETWEEN is that you have to put the lower bound first and the upper bound second; for example, if you write BETWEEN 5 AND 2, this always evaluates to FALSE because there is no value that can be greater than or equal to 5 while also being less than or equal to 2.
Here's a demo of the query in action at SQL Fiddle, and a list of the recognized INTERVAL expressions in MySQL.
Note that the parentheses around the expression NOW() - INTERVAL 14 DAY are not required but I would recommend using them here purely for the sake of clarity. It makes the predicate clause just a little bit easier to read in the absence of proper syntax highlighting, at the expense of two characters.
Ideally you should be using date types to store dates, but being that's not the case, you should look into casting to date then comparing.
select * from yourtable where cast (yourdate as Date) BETWEEN Date_Add(CURDATE(), INTERVAL -21 Day) and Date_Add(CURDATE(), INTERVAL -14 Day)
Note, this is untested and may need a little tweaking, but should give you a general idea of what you need to do.
Also, if it's possible, you should really look into converting the varchar field to a date field....they have date types to prevent this sort of thing from happening, although i know changing field types isn't always a possibility.
you can simply do with ADDDATE to get 14 days ago. compare string with date will work.
SELECT *
FROM your_table
WHERE your_date >= ADDDATE(NOW(), -14) AND your_date < NOW()
I use this for select data in past of past
SELECT * FROM Holidays
WHERE a.dDate >= DATE( NOW( ) ) - INTERVAL 14
DAY AND a.dDate <= DATE( NOW( ) ) - INTERVAL 8
Related
I need to know if there is an effective way in (My)SQL to do a select statement that resembles a for-loop in most programming languages. The simplest example would be to create a column with the values of 1 to 100. I have searched for solutions around (the one I found most interesting was one with cross joining each digit up to target length). In the end, I created a table named N (as in the maths symbol) in my db witha single column 'n' and values from 1 to 1 million.
Here's an example I've needed this:
select .....
cross join
(
select n,str_to_date(period_add(date_format(CURDATE(),'%Y%m'),n),'%Y%m') as 'date' from n where n<period_diff(201912,date_format(CURDATE(),'%Y%m'))
)
This returns a column with all the year/month combinations from curdate (happens to be march 2017) to Dec 2019. You can see the n used as a "variable" to add months and to calculate the "for loop's end condition". This works well. The question then is: is there a more elegant way to do this?
Your method is fine. I might be inclined to do:
select date_add(date_add(curdate(), interval 1 - day(curdate()) day), interval n.n month)
from n
where date_add(date_add(curdate(), interval 1 - day(curdate()) day), interval n.n month) <= '2019-12-01'
I prefer doing date arithmetic rather than going back and forth to strings.
The expression:
date_add(curdate(), interval 1 - day(curdate()) day)
is just a way of getting the first day of the month.
I'm trying to select data from a specific table in my database, but I want to be able to only view the last 3 days worth of data, I have the following code but for some reason I can't get it to work.
SELECT * FROM demands WHERE t.date >= DATE_ADD(CURDATE(), INTERVAL -3 DAY)
You may avoid usage of DATE_ADD() at all:
SELECT * FROM demands as t WHERE t.date >= (CURDATE() - INTERVAL 3 DAY)
As #OGHaza mentioned, you specified column with alias to nowhere: t.date should be just date (note that it is a reserved word, so you should use backticks around it in this case) or demands should be specified with an alias like demands as t.
I have a table 't' with date(yyyy-mm-dd), hour(1-12), minute(00-59), ampm(a/p), and timezone(pst/est) fields.
How can I select the rows that are <= now()? (ie. already happened)
Thank you for your suggestions!
edit: this does it without attention to the hour/minute/ap/tz fields:
SELECT * FROM t.date WHERE date <= now()
Here's one way to do it - combine all your seconds, minutes, etc into a date and compare to NOW(), making sure you do the comparison in the same time-zone. (Untested):
SELECT *
FROM t
LEFT JOIN y ON t.constant=y.constant
WHERE CONVERT_TZ(STR_TO_DATE(CONCAT(date,' ',hour,':',minute,' 'ampm),
'%Y-%m-%d %l:%i %p' ),
timezone,"SYSTEM") < NOW();
If your hour is 01 - 12 not 1-12 then use %h instead of %l in the STR_TO_DATE.
The STR_TO_DATE tries to stick your date and time columns together and convert them into a date.
The CONVERT_TZ(...,timezone,"SYSTEM") converts this date from whatever timezone is specified in the timezone column to system time.
This is then compared to NOW(), which is always in system time.
As an aside, perhaps you should make a single column date using MySQL's date datatype, as it's a lot easier to do arithmetic on that!
For reference, here is a summary of very useful mysql date functions where you can read up on those featuring in this answer.
Good luck!
SELECT * FROM t
WHERE `date`<=DATE_SUB(curdate(), INTERVAL 1 DAY)
OR (
`date`<=DATE_ADD(curdate(), INTERVAL 1 DAY)
AND
CONVERT_TZ(CAST(CONCAT(`date`,' ',IF(`hour`=12 AND ampm='a',0,if(ampm='a',`hour`,`hour`+12)),':',`minute`,':00') AS DATETIME),'GMT',`timezone`)<=NOW()
)
Rationale for date<=DATE_[ADD|SUB](curdate(), INTERVAL 1 DAY):
The fancy conversion is quite an expensive operation, so we don't want it to run on the complete table. This is why we pre-select against an UNCHANGED date field (possibly using an index). In no timezone can an event being more than a day in current timezone's past be in the future, and in no timezone can an event more than a day in the curent timezone's future be in the past.
I have two fields, one with the purchase date and one with the lifespan of an item. I am wondering if there is any way to determine if the current date is past the lifespan. So, pretty much if MySQL could test if current_date is > purchase_date + lifespan.
The purchase date is a date formated yyyy-mm-dd and lifespan is an integer of months. Is there any way to perform this calculation?
You might try:
SELECT * FROM table WHERE NOW() > (purchase_date + INTERVAL lifespan MONTH)
But you might use
SELECT * FROM table WHERE NOW() > date_add(purchase_date, INTERVAL lifespan MONTH)
Or DATEDIFF
SELECT * FROM table WHERE DATEDIFF(NOW(), purchase_date) / 30 < lifespan
How about using DATEDIFF?
Your query would be something along these lines:
SELECT * FROM table WHERE DATEDIFF(NOW(), purchase_date) < lifespan
Forgive me if my syntax is a little off, I don't have an SQL instance to test on right now
Yes it is possible, using the MySQL date and time functions.
hopefully this is an easy one.
I have a query that I want to produce results for todays date only based on a column (record_date) that uses CURRENT_TIMESTAMP.
so my query goes...
Select columns FROM fields WHERE table.record_date = DATE_SUB(NOW());
This is throwing up an error... :(
Thanks for you help....So i tried....
SELECT * FROM daily_record WHERE record_date = CURDATE()
but it yielded no result.
Here is a sample of the data in the column i am searching...
2011-03-31 11:28:37,
2011-03-31 11:28:37,
2011-03-31 11:28:37,
.....
Does it matter that the time is also saved?
Is that what you want ?
Select columns FROM fields WHERE table.record_date > CURDATE();
DATE_SUB() is for subtracting an interval from a date in MySQL. You've got DATE_SUB(now()), but don't specify an interval
It should be something like
... DATE_SUB(now(), INTERVAL 5 DAY);
so MySQL's complaining about the unexpected ), because of the missing interval.
If you want to convert 'now' into a date, you can simply use CURDATE(), or DATE(now())