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.
Related
I want to retrieve records from db according to date format YYYY,MM,dd given by me but the column type is YYYY,MM,dd hh:mm:ss.
tried to use Date format function
SELECT *
FROM tabl.error_logs
where created_at = DATE_FORMAT(NOW(),'%Y-%m-%d'- INTERVAL 3 DAY);
I expect the created date will be 2019-06-08, but the result is empty
What is the actual datatype of created_at column?
This answer is going to ignore that funkiness with the format with commas, and assume that it's not character type data, and that it's DATETIME or TIMESTAMP.
Normative pattern for predicates on DATETIME and TIMESTAMP columns is a range comparison.
For example, to get all datetimecol values on June 10th, then something like this:
WHERE t.datetimecol >= '2019-06-10 00:00:00'
AND t.datetimecol < '2019-06-11 00:00:00'
Typically, I would just pass that one date value, and let MySQL figure out the next day. If we omit the time portion, MySQL will assume 00:00:00
WHERE t.datetimecol >= '2019-06-10' + INTERVAL 0 DAY
AND t.datetimecol < '2019-06-10' + INTERVAL 1 DAY
For performance, to allow MySQL to make effective use of a range scan operation on a suitable index, we want to avoid wrapping the column reference in a function. That is, specifying DATE(t.datetimecol) in a condition in the WHERE clause is going to force MySQL to evaluate the DATE() function on every row in the table.
With references to the bare column, that allows MySQL to make use of an index, if a suitable index is available.
e.g.
SELECT e.*
FROM tabl.error_logs e
WHERE e.created_at >= DATE(NOW()) + INTERVAL -3 DAY
AND e.created_at < DATE(NOW()) + INTERVAL -2 DAY
note that we can easily test those expressions in the WHERE clause, to verify they are returning what we want, and tweak as necessary:
SELECT DATE(NOW()) + INTERVAL -3 DAY
, DATE(NOW()) + INTERVAL -2 DAY
To make your query sargable, you need ...
SELECT *
FROM tabl.error_logs
WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 3 DAY)
AND created_at < DATE_SUB(CURDATE(), INTERVAL 2 DAY)
This selects all values of created_at on or after midnight three days ago, up to but not including < midnight two days ago. It uses a range scan on an index on created_at if one is available.
You coudl use date_sub()
SELECT *
FROM tabl.error_logs
where date(created_at) = DATE_SUB(date(now()), INTERVAL 3 DAY);
if the column created_at is a date then you could avoid the date() function and let the index (if present) work for this column
SELECT *
FROM tabl.error_logs
where created_at = DATE_SUB(date(now()), INTERVAL 3 DAY);
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.
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
How do I subtract 30 days from the current datetime in mysql?
SELECT * FROM table
WHERE exec_datetime BETWEEN DATEDIFF(NOW() - 30 days) AND NOW();
SELECT * FROM table
WHERE exec_datetime BETWEEN DATE_SUB(NOW(), INTERVAL 30 DAY) AND NOW();
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add
To anyone who doesn't want to use DATE_SUB, use CURRENT_DATE:
SELECT CURRENT_DATE - INTERVAL 30 DAY
MySQL subtract days from now:
select now(), now() - interval 1 day
Prints:
2014-10-08 09:00:56 2014-10-07 09:00:56
Other Interval Temporal Expression Unit arguments:
https://dev.mysql.com/doc/refman/5.5/en/expressions.html#temporal-intervals
select now() - interval 1 microsecond
select now() - interval 1 second
select now() - interval 1 minute
select now() - interval 1 hour
select now() - interval 1 day
select now() - interval 1 week
select now() - interval 1 month
select now() - interval 1 year
Let's not use NOW() as you're losing any query caching or optimization because the query is different every time. See the list of functions you should not use in the MySQL documentation.
In the code below, let's assume this table is growing with time. New stuff is added and you want to show just the stuff in the last 30 days. This is the most common case.
Note that the date has been added as a string. It is better to add the date in this way, from your calling code, than to use the NOW() function as it kills your caching.
SELECT * FROM table WHERE exec_datetime >= DATE_SUB('2012-06-12', INTERVAL 30 DAY);
You can use BETWEEN if you really just want stuff from this very second to 30 days before this very second, but that's not a common use case in my experience, so I hope the simplified query can serve you well.
You can also use
select CURDATE()-INTERVAL 30 DAY
SELECT date_format(current_date - INTERVAL 50 DAY,'%d-%b-%Y')
You can format by using date format in SQL.
If you only need the date and not the time use:
select*from table where exec_datetime
between subdate(curdate(), 30)and curdate();
Since curdate() omits the time component, it's potentially faster than now() and more "semantically correct" in cases where you're only interested in the date.
Also, subdate()'s 2-arity overload is potentially faster than using interval.
interval is meant to be for cases when you need a non-day component.
another way
SELECT COUNT(*) FROM tbl_debug WHERE TO_DAYS(`when`) < TO_DAYS(NOW())-30 ;
I have a table where it stores the users.
And i want a query to find the users which are between eg 25 years old and 31 years old.
The age is stored at the mysql table as date (it stores the birthday).
(eg: 1980-02-25 (yyyy-mm-dd))
How the query should be written in order to find each time the people who are between two given ages?
Thanks.
You can either compute the necessary date range in your backend code, or in MySQL itself. Should you choose MySQL, here's what the query might look like:
SELECT user.* FROM user
WHERE birthdate >= DATE_SUB(NOW(), INTERVAL 31 YEAR)
AND birthdate <= DATE_SUB(NOW(), INTERVAL 25 YEAR)
There is also the somewhat shorter BETWEEN clause for MySQL. I'd recommend CURDATE() instead of NOW() because it does not have the time component.
SELECT * FROM user
WHERE birthdate
BETWEEN
(CURDATE() - INTERVAL 31 YEAR)
AND
(CURDATE() - INTERVAL 25 YEAR)
Note: it's inclusive.