MYSQL: automatically extract the YEAR from the date input into another column - mysql

I have a table with a dateOfBirth column and a yearOfBirth column. The input only contains the DOB information. What I am looking for is to just insert DOB info into the db, and the mysql will auto update the year column field with the year extracted from the date inserted. Is it possible to be done?
Right now my MySQL query is just
INSERT INTO table
(name, dateOfBirth, yearOfBirth)
VALUES (?)
How should I change that?

It is possible to do this using a trigger, but I don't see any practical reason to do it. Instead, just leverage the YEAR() function if you want to present the year in a query:
SELECT
name,
dateOfBirth,
YEAR(dateOfBirth) AS yearOfBirth
FROM yourTable;
Storing the birthdates in a bona fide date column is the best design choice, and any derivative of that can be had using a function or cast.
Edit:
If your reason for wanting to do this is adding an index by year, you can instead just add an index on the dateOfBirth field:
CREATE INDEX idx ON yourTable (dateOfBirth)
If you wanted to query for a certain year, say 2018, you could try the following:
SELECT *
FROM yourTable
WHERE dateOfBirth >= '2018-01-01' AND dateOfBirth < '2019-01-01';
This in fact would be sargable, meaning that the index we created above could be used.

Related

MYSQL query disallowing a timestamp column having two values from the same date

For example if a user inserts '2017-03-13 12:16:18.0' into the timestamp column,
the same user should not be allowed to enter another value in this column IF IT'S ON THE SAME DAY i.e 2017-03-13 (in this case). Or ultimately, update the timestamp column with the previously inserted value ('2017-03-13 12:16:18.0') each time the user tries to insert a timestamp date twice ON THE SAME DAY. I hope I've been explicit enough.
Below is a non-functioning query I came up with, but it shows what I would like the query to do ultimately. Thanks for your help and feedbacks.
INSERT INTO hr.entry(id,entry_time)
VALUES (45,
CASE WHEN '13-03-2017'= CAST(SYSDATE() AS date) THEN
(UPDATE hr.entry
SET entry_time =
(SELECT entry_time
FROM hr.entry
WHERE id=45
AND CAST(entry_time AS date)= CAST(SYSDATE() AS date) )
ELSE
SYSDATE());
You could add a DATE column to your table, and add a unique index to that column. Then, when you insert the timestamp into the timestamp column, you could also insert the date from that timestamp into the DATE column. Attempts to insert a timestamp whose date component already exists in that table would cause MySQL to throw an error.
I think you are going to need a trigger, unless you store the timestamp as a string using YYYY-MM-DD HH:MI:SS format. I don't really recommend that.
So, create a trigger that updates a column called timestamp_date. This simply extracts the date part of the timestamp.
With this column, you can define a unique index:
create unique index entry_userid_timestampdate on entry(userid, timestamp_date);
This will then enforce your condition.
If you decide that you want to store the timestamp as a string, you don't need the trigger (although will need to manually set the "timestamp"). Instead, you can use a prefix:
create unique index entry_userid_timestampstr on entry(userid, left(timestamp_date, 10));

I need a query to delete a row if a date is expired

Here is my query:
DELETE FROM `upcoming` WHERE `Date` < DATE_FORMAT(CURDATE(), '%M-%d-%y')
When I run it, it deletes every thing in my table.
Date is the column where I put the upcoming event dates.
This is what i have in my table.
It should only delete the one date not both of them.
Table:
12-25-13
11-11-13
Todays date:
11-25-13
Try
DELETE FROM `upcoming` WHERE STR_TO_DATE(`Date`, '%M-%d-%y') < DATE_FORMAT(CURDATE(), '%M-%d-%y')
The normative pattern is to use DATE datatype to store date values.
It appears you are storing your "date" values as VARCHAR, in format 'mm-dd-yy'. Comparisons of VARCHAR expressions is performed character by character, from left to right. The character representation, with the month first, is not in canonical order, that is, a sort of the mm-dd-yy values will not be sorted in date order, e.g. '01-01-13' (Jan 2013) will sort before '11-27-12' (Nov 2012).
The simplest approach, in terms of a SQL statement, is to convert the VARCHAR into a DATE datatype, and compare that to an expression that also returns a DATE.
DELETE FROM `upcoming` WHERE STR_TO_DATE(`Date`,'%m-%d-%y') < CURDATE()
In terms of performance, MySQL can't perform an index range scan to satisfy this predicate. Every row in the table will need to be examined, to do the conversion, and then the comparison. If the column were stored as a DATE, then the bare column could be referenced in the predicate and MySQL could use an index range scan.
ALSO: '%M' format specifier returns the month name, 'January','February', etc. The '%m' specifier returns numeric month '01','02'.

records from table where date between two years

I need to get the record from one table where date between June-30-2011 and June-30-2012.
the problem is that the result is just only display the records of year 2012 although the table has records for year 2011.
below is my code
SELECT * FROM tbl_name where date between '06/30/2011' and '06/30/2012'
you need to convert it bact to date using STR_TO_DATE, eg
SELECT *
FROM tbl_name
where STR_TO_DATE(date, '%m/%d/%Y') between '2011-06-31' and '2012-06-31'
STR_TO_DATE
It is not good to store Dates as string on database because as you see it is hard to search for it, you need some extra functions to convert it back to date and to which I think it kills the index.
If you have time or privilege to alter, fix the values and change it to DateTime data type.

Select Date(String Date)<DATE(Text Column with Date)

I have a table with a column of the type text where I store various settings, including dates, using NOW() in the insert query.
Now I want to get all rows from this table where this column is before a specific date (e.g. 2012-09-19).
Comparing via DATE(date_column)<DATE(NOW()) is easy, but I don't know how to pass a specific date instead of NOW(), because date formats of the input string may differ.
Here's a sample code:
INSERT INTO table (date_column) VALUES (NOW())
And when selecting:
SELECT * FROM table WHERE DATE(date_column)<DATE('2012-09-19');
EDIT: The above code actually works. I was missing the quotes around the date initially.
Avoid placing functions around your column types (WHERE FUNCTION(col) ...). This decreases performance. You want to have a table that has domain integrity, meaning if you are storing a date, it is a date type.
To select records that match your date, simply encase your YYYY-MM-DD date in quotes:
SELECT * FROM table WHERE date_column < '2012-09-19'
If date_column truly is of type DATE, you don't need to run DATE() on it.
Also note that running DATE() on date_column will prevent MySQL from using any indexes, so you'll be doing a table scan.
Try:
WHERE date_column < '2012-09-19'

Is CREATE_DATE a pre-defined table column?

In this question does CREATE_DATE refer to a user defined column or a pre-defined mySQL column? If it is user defined what is a good assumption on what type the column is?
Select all records from table REPORTS that have a CREATE_DATE before
July 9th 2006 in newest - oldest order.
CREATE_DATE is not a pre-defined column name; it would have been defined as part of the CREATE TABLE statement.
Most likely, it is going to be a MySQL DATETIME type, though it could also be the simpler DATE type. See MySQL date types for more information.
The difference between the DATETIME and DATE types is that DATETIME (as its name implies) includes a timestamp as well as the date, while DATE stores only the date part.
SELECT * FROM REPORTS WHERE CREATE_DATE < '2006-07-09' ORDER BY CREATE_DATE DESC