I have a table with a year and month in different columns, and I need to find all rows between 3 months ago and now.
SELECT * FROM `table`
WHERE DATE(CONCAT(`year`, '-', `month`, '-01')) >=
DATE_FORMAT(NOW() - INTERVAL 3 MONTH, '%Y-%m-01')
It just seems rather verbose, and possibly inefficient as this is a very large table. Is there a better way to do this?
There isn't much optimization to be had when the date is stored as separate fields, but I would re-write your query as:
SELECT *
FROM `table`
WHERE STR_TO_DATE(`year`+ '-'+ `month` + '-01', '%Y-%m-%d') >= DATE_SUB(NOW(), INTERVAL 3 MONTH)
The concatenation renders indexing on the year and month columns useless.
For more info about MySQL date functions, see: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html
Well, I had the same issue and I have figured what I think is the solution for this case.
SELECT *
FROM table
WHERE (month >= (month(curdate()) - 3 AND year >= year(curdate()))
AND (month >= month(curdate()) AND year >= year(curdate())))
Supposing you have columns named year and month.
Related
I want to display last 12 months sales in a chart. SQL table has year and month field and not a combined date field.
Im not able to give the interval condition of 12months on Year field.
SELECT s_month,s_year,SUM(s_amount) FROM table
WHERE s_month >= Date_add(now(),interval - 12 month)
AND s_year >= Date_add(now(),interval - 12 month)
GROUP BY s_year,s_month
One method is:
select s_year, s_Month, sum(s_amount)
from t
where date(concat_ws('-', s_year, s.month, 1)) >= curdate() - interval 12 month
group by s_year, s_month;
You may want to adjust the date arithmetic, depending on whether you want the date from 12 months ago.
If you want the last 12 months in the data, you can do:
select s_year, s_month, sum(amount)
from t
group by s_year, s_month
order by s_year desc, s_month desc
limit 12;
This is a strong argument against storing date parts (month, year) in separate columns.
The WHERE clause you have does not do what you expect!
It is virtually always better to have a DATE column (or TIMESTAMP or DATETIME) and use date functions as needed to split it apart.
SELECT MONTH(dat), YEAR(dat), SUM(amount)
FROM table
WHERE dat >= CURDATE() - INTERVAL 12 MONTH
GROUP BY LEFT(dat, 7) -- eg, "2017-12"
There is another problem with your query. SUM(amount) will have a partial month at either end. I can't solve that for you without better understanding where the data comes from and when. If it is already a single reading stored on the first of the month, then no problem. If it is daily or hourly amounts, then my point stands.
Given a set of data with date_created stored like 2017-04-13 23:29:52, how would I construct an SQL query to select all items that were created within the last 3 hours?
I originally thought to do something like this:
SELECT
*,
MAX(date_created)
FROM items
GROUP BY date_created
but that would not be exactly what I want. I'm not sure how to go about this.
Use NOW() and INTERVAL in your WHERE clause
SELECT * FROM items WHERE date_created <= NOW() - INTERVAL 180 minute AND date_created >= NOW() - INTERVAL 210 minute
This one uses CURDATE, CURDATE and DATE_ADD:
SELECT *
FROM items
WHERE DATE(date_created) = CURDATE()
AND TIME(date_created) BETWEEN CURTIME() AND DATE_ADD(CURTIME(), INTERVAL -3 HOUR)
select * from items where
extract(hours from age(current_timestamp, date_created))>=3;
Extract keyword would extract hours difference from current timestamp and return only that is greater than or equal to 3.
what will be the smartest way to select all rows from MySQL table for the past 3 months if the table has the following columns:
| id (int) | year (int)| month (int) |
Considering that if the current month & year are for example 2.2016 I need to select all records for 11.2015 & 12.2015 & 1.2016
It is easy if the current month is greater than 3 because all months that I need to select are in the same year so I can subtract 3 from the current month and run simple query
SELECT * FROM mytabe where year=2016 and month >= xx
Select * from mytable where STR_TO_DATE(concat(year,"-",month,"-01"),'%Y-%m-%d')>date_sub(curdate(),Interval 3 month) ;
The above query will get fetch year and month from date 3 months before today
You can select three Months records by these queries follow this.
The columnName means which column data want you select.
The tableName means which table data want you select.
The dateColumnName means which column date base you want to select data.
It would return Last Month data from today.
SELECT columName FROM tableName WHERE dateColumName BETWEEN ( DATE(NOW()) - INTERVAL 1 MONTH) AND Date(Now())
It would return Second Last Month data from today.
SELECT columName FROM tableName WHERE dateColumName BETWEEN ( DATE(NOW()) - INTERVAL 2 MONTH) AND ( DATE(NOW()) - INTERVAL 1 MONTH)
It would return Third Last Month data from today.
SELECT columName FROM tableName WHERE dateColumName BETWEEN ( DATE(NOW()) - INTERVAL 3 MONTH) AND ( DATE(NOW()) - INTERVAL 2 MONTH)
May It help to others.
Please try this
Select * from mytable where STR_TO_DATE(concat(year,"-",month,"-01"),'%Y-%m-%d')>date_sub(curdate(),Interval 3 month) ;
I have tried to filter records but with the use of now function as given below
select * from table where date>= DATE_SUB( NOW( ) ,INTERVAL 90 DAY )
What I need is a select statement that can filter its records for a week or month from the current date but without using NOW() function
if you are using java you could make use of the following code
String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime());
or you could use curdate() of mysql
Since I found it hard to understand the question I provide the following possibilities:
Try for all dates in a week from now:
SELECT * FROM table
WHERE date BETWEEN CURDATE() AND DATE_ADD(CURDATE() ,INTERVAL 1 WEEK)
and for all dates in a month from now:
SELECT * FROM table
WHERE date BETWEEN CURDATE() AND DATE_ADD(CURDATE() ,INTERVAL 1 MONTH)
If you are looking for all dates of the current month use
SELECT * FROM table
WHERE MONTH(date)=MONTH(CURDATE()) AND YEAR(date)=YEAR(CURDATE())
or for all dates of the current week use
SELECT * FROM table
WHERE WEEK(date)=WEEK(CURDATE()) AND YEAR(date)=YEAR(CURDATE())
So I can get the days with SELECT DATEDIFF(CURDATE(),expires) but not exactly a month with an output of one (1). Isn't this anyhow possible to transform it to month in MySQL? I want to check if a given date (like expires) is >= 1.
SELECT
...
FROM
tablename
WHERE
expires<=DATE_SUB(CURDATE(), INTERVAL 1 MONTH);
Will get you all rows, that have expired a month ago or earlier
Use following query
Select * from
table_name where TIMESTAMPDIFF
(MONTH,
ADDDATE(LAST_DAY(SUBDATE(expires, INTERVAL 1 MONTH)), 1),
ADDDATE(LAST_DAY(SUBDATE(CURDATE(), INTERVAL 1 MONTH)), 1)
)>=1