I have a sql file containing bYear and u_age column in users table.
I would like to know how I can change all the digits in bYear, such as 1986, 2000, to u_age such as 33, 19.
Thanks so much !!
If you are looking to update the table (not the file), you can just do:
update users set u_age = year(curdate()) - bYear;
curdate() gives you the current date, from which you can extract the year using the year() function.
Please note that this computation is not accurate at all: to compute an age, you need the entire date of birth (including month and day). The above computation behaves like the date of birth is actually the first day of year bYear.
If you are looking to update a sql file: as commented by Raymond Nijland, just don't. This is much more complicated and far less efficient. Instead, load the file in a table, update the table and then export it to a file
Related
I want to get the date of birth of a cat as a range of years.
The year range is as follows, and several selections are possible.
Year : [2000, 2010, 2020]
If I select 2020, the period from 2020-01-01 to 2029-12-31.
If I select 2000, 2020, the period from 2000-01-01 to 2009-12-31 and 2020-01-01 to 2029-12-31.
<TABLE>
CAT {
ID number,
Birth DateTime,
...
}
I have searched for various ways through books and Google, but I can't find the way I want to do so..
select * from CAT
where birth between '2000-01-01' and '2009-12-31'
or birth between '2010-01-01' and '2019-12-31'
or birth between '2020-01-01' and '2029-12-31'
I tried to use 'Between' or '-01-01', but if [2000, 2020] is selected, it must be connected with 'or'.
The more or, the slower the speed.
Please tell me a good way to do range calculations being able to use index.
The index is being used for BirthDate.
Add) In my db, the query of 'SUBSTRING(YEAR(CAT.birth),1,3) IN (200,202)' works quickly.
I have 500,000 data, can I use it like this?
All you need to do is add index to column birth and run your query above with BETWEEN and OR.
if you are using mysql, did you tried with YEAR() function ?
Example:
SELECT * FROM cat WHERE YEAR(birth) BETWEEN 1990 AND 2018 ORDER BY YEAR(birth) ASC;
Please check this Mysql YEAR()
If you expect to get more than about 20% of the rows from a table, then an INDEX will be eschewed for simply scanning all the rows.
Otherwise, having INDEX(birth) will help with certain queries, but none of the ones mentioned so far. Each of them is not "sargable" .
To use the index (and be efficient for a limited range of years or date range), something like this is probably what you need. This example covers 2 calendar years.
WHERE CAT.birth >= '2018-01-01'
AND CAT.birth < '2020-01-01'
BTW: SUBSTRING(YEAR(CAT.birth),1,3) can be simplified to LEFT(CAT.birth, 3), but that still cannot use the recommended index.
BTW: A 'bug' in your code: Since birth is a DATETIME, and '2009-12-31' excludes but midnight of the morning of New Year's Eve. Note how I avoided this common 'bug' by using < and the next day. This works whether you have DATE, DATETIME or DATETIME(6), etc.
So I have to store a particular date of the year, any year. So I will only be needing the date and month part of a date.
I can either store it with any year and just ignore it on the programming side but that feels dirty. Any better way to handle this?
Closest I could find was this one but that includes time component as well and goes on some different tangent.
If you're using MySQL >= 5.7.6, you could use a generated column. A trivial example table would look like this (untested as, ironically, I don't have access to a recent MySQL server right now):
CREATE TABLE myTable (
the_date DATE,
month_date VARCHAR(5) AS CONCAT(MONTH(the_date), '-', DAY(the_date))
);
Of course, change the generated value according to your needs (different separator, padding with zeroes on the month, etc.)
If you're stuck with an older version, you could perform a similar conversion using a view.
What is wrong with just having a DATE column value, in this example called my_date :
SELECT MONTH(my_date) AS myMonth, DAY(my_date) AS myDay, <othercolumns>
FROM table WHERE id = 1
Then you can use your PHP to get your row and output $row['myMonth'], etc.
You can also output the MONTH / DAY values as any format string you like using MySQL DATE_FORMAT .
You can also CONCAT these two values if you need them in a single column.
SELECT CONCAT(MONTH(my_date),' ',DAY(my_date)) as month_day, <othercolumns>
FROM table WHERE id = 1
Warning:
Storing dates as 0000-00-00 is perfectly valid but MySQL year 0000 is not a leap year so you can not store 0000-02-29, this will instead be saved as a default 0000-00-00.
You might as well use a default year value that is leap year safe (such as year 2k) if you're sure you're never going to use the year value. such as (2000-XX-XX).
You could store the Julian Date as an integer, and convert to Georgian Month/Day when you need it. This can keep things quite clean. Keep your eyes peeled for the leap year.
The notion of Julian here is truly, just "Day of year" and converting when needed.
function getDateFromDay($dayOfYear, $year) {
$date = DateTime::createFromFormat('z Y', strval($dayOfYear) . ' ' . strval($year));
return $date;
}
so i have a table with hundreds records. And a have a filed name "created" type with a datetime format. Now I want to make and archive with the months. For example January, February.... etc. I need to create query to find all possible months. For example if my records start from 2011/05/01 to now I will need to fetch the months that means months 5,6,7,8,9,10,11,12.
Is there a way to that ???
If you are looking at the list of all Months present in the created field (as I understand your query) then do this:
SELECT DISTINCT(MONTH(created)) FROM posts;
The resulting set would be the list of unique months in the field. If this will complain then try:
SELECT DISTINCT(MONTH(DATE(created))) FROM posts;
You can then substitute MONTH for MONTHNAME and get names instead. I did not add the WHERE clause to these queries but you can limit the dataset you are looking at as you see fit.
For more information take a look at http://dev.mysql.com/doc/refman/5.1/en/functions.html this has a list of quite a few functions that MySQL natively provides.
Yes, use the DATE_FORMAT function and other date and time functions.
More details here
For example, if you want all your records for December 2011:
SELECT * FROM posts WHERE YEAR(created) = 2011 AND MONTH(created) = 12
If I have MySQL query like this, summing word frequencies per week:
SELECT
SUM(`city`),
SUM(`officers`),
SUM(`uk`),
SUM(`wednesday`),
DATE_FORMAT(`dateTime`, '%d/%m/%Y')
FROM myTable
WHERE dateTime BETWEEN '2011-09-28 18:00:00' AND '2011-10-29 18:59:00'
GROUP BY WEEK(dateTime)
The results given by MySQL take the first value of column dateTime, in this case 28/09/2011 which happens to be a Saturday.
Is it possible to adjust the query in MySQL to show the date upon which the week commences, even if there is no data available, so that for the above, 2011-09-28 would be replaced with 2011/09/26 instead? That is, the date of the start of the week, being a Monday. Or would it be better to adjust the dates programmatically after the query has run?
The dateTime column is in format 2011/10/02 12:05:00
It is possible to do it in SQL but it would be better to do it in your program code as it would be more efficient and easier. Also, while MySQL accepts your query, it doesn't quite make sense - you have DATE_FORMAT(dateTime, '%d/%m/%Y') in select's field list while you group by WEEK(dateTime). This means that the DB engine has to select random date from current group (week) for each row. Ie consider you have records for 27.09.2011, 28.09.2011 and 29.09.2011 - they all fall onto same week, so in the final resultset only one row is generated for those three records. Now which date out of those three should be picked for the DATE_FORMAT() call? Answer would be somewhat simpler if there is ORDER BY in the query but it still doesn't quite make sense to use fields/expressions in the field list which aren't in GROUP BY or which aren't aggregates. You should really return the week number in the select list (instead of DATE_FORMAT call) and then in your code calculate the start and end dates from it.
I have the following table in MySQL that records event counts of stuff happening each day
event_date event_count
2011-05-03 21
2011-05-04 12
2011-05-05 12
I want to be able to query this efficiently by date range AND by day of week. For example - "What is the event_count on Tuesdays in May?"
Currently the event_date field is a date type. Are there any functions in MySQL that let me query this column by day of week, or should I add another column to the table to store the day of week?
The table will hold hundreds of thousands of rows, so given a choice I'll choose the most efficient solution (as opposed to most simple).
Use DAYOFWEEK in your query, something like:
SELECT * FROM mytable WHERE MONTH(event_date) = 5 AND DAYOFWEEK(event_date) = 7;
This will find all info for Saturdays in May.
To get the fastest reads store a denormalized field that is the day of the week (and whatever else you need). That way you can index columns and avoid full table scans.
Just try the above first to see if it suits your needs and if it doesn't, add some extra columns and store the data on write. Just watch out for update anomalies (make sure you update the day_of_week column if you change event_date).
Note that the denormalized fields will increase the time taken to do writes, increase calculations on write, and take up more space. Make sure you really need the benefit and can measure that it helps you.
Check DAYOFWEEK() function
If you want textual representation of day of week - use DAYNAME() function.