mysql convert date to same date of current year - mysql

How can I replace the year of a date column with that of the current year?
the following returns NULL
SELECT str_to_date(concat(year(now()), '-',
month(datecolumn), '-' ,day(datecolumn)), '%Y-%M-%D')
FROM TABLE

Khalid's answer is correct most of the time. Leap year messes things up! If you run the proposed query where the value of datecol is '2016-02-29' and the CURRENT_DATE is '2017-01-01', for example, you get null.
An alternate way to do this that handles leap year more gracefully is like this:
SELECT DATE_FORMAT(
MAKEDATE(YEAR(CURRENT_DATE()), DAYOFYEAR(datecol)),
'%Y-%m-%d'
) `date`
FROM t
The value of date here would be 2017-03-01.
Edit/clarification: The problem is that changing the year of '2016-02-29' to 2017, for example, produces '2017-02-29', which is not a valid date. Then, running DATE_FORMAT('2017-02-29', '%Y-%m-%d') results in null. A demo of the problem is here:
http://sqlfiddle.com/#!9/c5358/11
However, after reviewing my answer I realized that I another problem by using MAKEDATE since any date on a leap year after Feb 28 is days+1 for a "normal" year with 365 days. For example, if datecol = '2016-03-01' and the current year were 2017 then the converted date would be '2017-03-02', not '2017-03-01' as desired. A better approach is as follows:
SELECT
DATE_FORMAT(DATE_ADD(datecol, INTERVAL (YEAR(CURRENT_DATE()) - YEAR(datecol)) YEAR), '%Y-%m-%d') `date`
FROM t;
This method turns any Feb 29th into the 28th, and otherwise keeps all other dates exactly as you'd expect them. A demo of the solution is here:
http://sqlfiddle.com/#!9/c5358/12

You can do so
SELECT
CONCAT(YEAR(CURRENT_DATE()),RIGHT(datecol,15)) `date`
FROM t
Demo
Or for date only
SELECT
DATE_FORMAT(
CONCAT(YEAR(CURRENT_DATE()),RIGHT(datecol,15))
,'%Y-%m-%d') `date`
FROM t
Demo 2

Related

how to add one year from the most recent date in the same table from SQL?

so I create a query that managed to add one year from the most recent date in the same table like this:
DATE_ADD(SELECT max(order_date) FROM order WHERE id_order = '$id', INTERVAL 1 YEAR)
but it gave an error near SELECT
A subquery needs to be in its own set of parentheses. But in this case, it is better to put the calculation in the subquery:
(SELECT DATE_ADD(max(order_date), INTERVAL 1 YEAR)
FROM order
WHERE id_order = '$id'
) as colname
Addition to a date works in the order of days. So you just need the most recent (max) date and add 365 days to it:
SELECT
MAX(order_date) + 365
FROM order
Fair point made by Widor that this is basic arithmetic so does not take into account leap years. Certain RDBMS INTERVAL arithmetic have bugs with leap years too. Now the question has been clarified as mysql, see Gordon Linoff's answer using DATE_ADD and the mysql INTERVAL

SQL - Get result of current year only

How can I get the result of the current year using SQL?
I have a table that has a column date with the format yyyy-mm-dd.
Now, I want to do select query that only returns the current year result.
The pseudo code should be like:
select * from table where date is (current year dates)
The result should be as following:
id date
2 2015-01-01
3 2015-02-01
9 2015-01-01
6 2015-02-01
How can I do this?
Use YEAR() to get only the year of the dates you want to work with:
select * from table where YEAR(date) = YEAR(CURDATE())
Using WHERE YEAR(date) = YEAR(CURDATE()) is correct but it cannot use an index on column date if exists; if it doesn't exist it should.
A better solution is:
SELECT *
FROM tbl
WHERE `date` BETWEEN '2015-01-01' AND '2015-12-31'
The dates (first and last day of the year) need to be generated from the client code.
When I tried these answers on SQL server, I got an error saying curdate() was not a recognized function.
If you get the same error, using getdate() instead of curdate() should work!
--========= Get Current Year ===========
Select DATEPART(yyyy, GETDATE())
SELECT id, date FROM your_table WHERE YEAR( date ) = YEAR( CURDATE() )
SELECT
date
FROM
TABLE
WHERE
YEAR (date) = YEAR (CURDATE());
If the date field contains a time component, you want to include December 31 so you have to go to January 1 of the next year. You also don't have to use code to insert dates into the SQL. You can use the following
SELECT * FROM table
WHERE date BETWEEN MAKEDATE(YEAR(CURDATE()), 1) AND MAKEDATE(YEAR(CURDATE())+1, 1)
This will give you January 1st of the current year through January 1st at midnight of the following year.
As #Clockwork-Muse pointed out, if the date field does not contain a time component, you would want to exclude January 1 of the following year by using
WHERE date >= MAKEDATE(YEAR(CURDATE()), 1) AND date < MAKEDATE(YEAR(CURDATE())+1, 1)
You can do this using SQL DATE_FORMATE(). like below:
SELECT
date
FROM
TABLE
WHERE
DATE_FORMAT(date, '%Y') = YEAR (CURDATE());
SELECT [ID]
,[datefield]
FROM [targettable]
WHERE DATEPART(YYYY, [datefield]) = (SELECT TOP 1(MAX(DATEPART(YYYY, [datefield])))
FROM [targettable]
)
/*
This will find the newest records in the table regardless of how recent the last time data was entered.
To grab the oldest records from the table do this
SELECT [ID]
,[datefield]
FROM [targettable]
WHERE DATEPART(YYYY, [datefield]) = (SELECT TOP 1(MIN(DATEPART(YYYY, [datefield])))
FROM [targettable]
)
*/

Select Range of Items by Year and Month

I'm attempting to create a select statement which gets items by year and month.
This is what I have so far:
SELECT * FROM sales WHERE YEAR(Date) = 2013 AND MONTH(?) = 'June'
I can't merely select date ranges because different months have different number days. It would be ideal to select months by their number (ie, January being 1) or a similar approach.
How is this worked out in a mysql statement?
The fields are datetime fields such as 2012-12-01 00:00:00
Have a look at the performance and write your condition as
SELECT * FROM sales
WHERE
Date >= '2013-06-01 00:00:00'
AND
Date < '2013-07-01 00:00:00'
for the example month: June of 2013
so MySQL can use an index on the column date. You will get exactly all rows with a date in the June of 2013, even those in the first second, but not those in the first second of the July of 2013.
You see, that you don't need to know the number of days of the particular month, because you will ever use the first of both months.
You could use a bit of date calculation too:
SELECT * FROM sales
WHERE
Date >= '2013-06-01 00:00:00'
AND
Date < '2013-06-01 00:00:00' + INTERVAL 1 MONTH
so you need only to know the start and the length of the interval.
Note
The most important part of my answer is to use the column Date without using a function on this column, so MySQL can use an index.

Changing year in mysql date

I have a bunch of dates in our database stored in the standard mysql date type.
How can I covert a year to 2013, regardless of original date.
So if a date is 2009-01-01 it would be 2013-01-01, but if it's 2012-01-04, it'd convert to 2013-01-14.
I figured it'd be simple and obvious, but I couldn't figure it out =/
That's simple:
for DATETIME:
UPDATE table_name
SET date_col=DATE_FORMAT(date_col,'2013-%m-%d %T');
for DATE:
UPDATE table_name
SET date_col=DATE_FORMAT(date_col,'2013-%m-%d');
The problem with the current answers is that none of them take leap year into account. If you take the date '2016-02-29' and convert it to the year 2013 through concatenation, you get '2013-02-29', which is not a valid date. If you run DATE_FORMAT('2013-02-29', '%Y-%m-%d') the result is null. See an example here:
http://sqlfiddle.com/#!9/c5358/11
A better way to change the year is to use DATE_ADD since it accounts for daylight savings. For example:
SELECT
DATE_FORMAT(DATE_ADD(datecol, INTERVAL (YEAR(CURRENT_DATE()) - YEAR(datecol)) YEAR), '%Y-%m-%d') `date`
FROM t;
You could substitute CURRENT_DATE() with '2013-01-01' if you still wanted to convert all dates to 2013 instead of the current year. An example of this solution is here:
http://sqlfiddle.com/#!9/c5358/12
UPDATE tableName
SET dateColumn = dateColumn + INTERVAL 4 YEAR
SQLFiddle Demo
other way is to concatenate it,
UPDATE Table1
SET DateColumn = CONCAT(YEAR(CURDATE()), '-', DATE_FORMAT(dateColumn, '%m-%d'))
SQLFiddle Demo
If its a date field:
UPDATE table_name SET date_field_name = CONCAT("2013", RIGHT(date_field_name,6));
If its a date time field:
UPDATE table_name SET date_field_name = CONCAT("2013", RIGHT(date_field_name,15));
Current date from quest was 2013, I understand that you wish set current YEAR in date.
UPDATE table_name SET date_col=DATE_FORMAT('2013-05-06',YEAR(CURRENT_DATE)-%m-%d);

I need to select a specific range of dates, ignoring year, from MySQL table

Here's my problem. My system stores dates and times in your usual DATETIME format:
'YYYY-MM-DD HH:MM:SS'
This is what I have trouble with:
I need to select all the contacts that have a date field in this format:
'XXXX-12-02 23:59:59' and every other date 7 days leading up to it.
For example, I would need to get all these rows with these dates in response:
1965-12-02
1985-11-28
1990-12-01
Is this possible and if it is, any help or tips that you can give me?
The easy part: To find any date on the same day and month:
SELECT .... FROM .... WHERE
month(timefield)=month('2012-12-02 23:59:59')
and day(timefield) = day('2012-12-02 23:59:59)
A messy way of doing it, but it will (mostly) work is to do a
SELECT .... FROM .... WHERE
(month(timefield)=month('2012-12-02 23:59:59')
and day(timefield) = day('2012-12-02 23:59:59')) or
(month(timefield)=month(date_sub('2012-12-02 23:59:59' interval 1))
and day(timefield) = day(date_sub('2012-12-02 23:59:59') interval 1)) or
(month(timefield)=month(date_sub('2012-12-02 23:59:59' interval 2))
and day(timefield) = day(date_sub('2012-12-02 23:59:59') interval 2)) or
and so on...
Then the problem comes up: What with leap years... I do not have any good solutions for that... If e.g your seed date is 05-mar-2012, then you will only get back to 28-feb-2012, but I guess you want the data back to 27 feb 2011... One possible solution to that is to make sure that you always normalize the date to a leap year, fetch the days 8 days back and throws away what you do not want in the front end.
You can get a specific part of your DATETIME variable using the following functions.
DAY(your_DATETIME_Variable) --> gets day as integer
MONTH(your_DATETIME_Variable) --> gets month as integer
YEAR(your_DATETIME_Variable) --> gets year as integer