Automatically update a database column - mysql

Another answer shows how to set a default timestamp. However, it updates only the entry you edit. I was wondering if there is another way that would edit, let's say, the current year in all the entries.
For example, my database has 2 entries that were inserted in the year 2011, so the current date column for the 2 entries would be 2011. I would like to make this column update to 2012 when a new user is inserted, which means now there would be 3 entries and the current year column for all 3 entries would be 2012.
Is this possible?
My main objective is to calculate age.

You really don't need to - and should NOT - store the current year in a table's column (and possibly in several million rows) - unless you are writing a Star Trek application where some characters live in 2012 and others in 42012 (in other words if the "current year" is not the same for all).
You can always use this in your computations:
YEAR( CURRENT_DATE() )

If you store the user's birthdate as a DATE column then you can calculate their age. These calculations range from the "good 99%' of the time, to the good for everyone including leap year babies

Related

Date table lookup efficiency - MySQL

I need to calculate the number of "working minutes" between two datetime values, lets call them 'Created' and 'Finished'.
'Finished' is always subsequent to 'Created'. The two values can differ by anything from 1 second to several years. The median difference is 50,000 seconds or roughly 14 hours.
Working minutes are defined as those occurring between 0900 to 1700 hours, Monday to Friday; excluding weekends and official holidays in our country.
I decided a lookup table was the way to go, so I generated a table of all work minutes, explicitly excluding weekends, nights and holidays...
CREATE TABLE `work_minutes` (
`min` datetime NOT NULL,
PRIMARY KEY (`min`),
UNIQUE KEY `min_UNIQUE` (`min`)
)
I populated this programatically with all the "working minutes" between years 2017 to 2024, and at this point I started to get the feeling I was being very inefficient as the table began to balloon to several hundred thousand rows.
I can do a lookup easily enough, for instance:
SELECT COUNT(min) FROM `work_minutes` AS wm
WHERE wm.min > '2022-01-04 00:04:03'
AND wm.min <= '2022-02-03 14:13:09';
#Returns 10394 'working minutes' in 0.078 sec
This is good enough for a one-off lookup but to query a table of 70,000 value pairs takes over 90 minutes.
So, I am uncomfortable with the slowness of the query and the sense that the lookup table is unnecessarily bloated.
I am thinking I need to set up two tables, one just for dates and another just for minutes, but not sure how to implement. Date logic has never been my forte. The most important thing to me is that the lookup can query over 70,000 values reasonably quickly and efficiently.
Working in MySQL 5.7.30. Thanks in advance for your expertise.
Divide the timerange to 3 parts - starting and finishing incomplete day parts, and middle part which consists from a lot of complete days. Of course if both starting and finishing time stamps have the same date part then it will be one part only, if their dates are consecutive then you\ll have 2 parts to process.
There is no problem to calculate the number of working minutes in incomplete day part. Common overlapping formula with weekday checking will help.
Create static calendar/service table which starts from the date which is earlier than any possible date in your beginning timestamp with guarantee and includes all dates after any possible date in your finishing timestamp. Calculate cumulative working minutes for each date in the table. This table allows to calculate the amount of working time in any range of complete days with single substraction.
Plan A: Convert the DATETIME values to seconds (from some arbitrary time) via TO_SECONDS(), then manipulate them with simple arithmetic.
Plan B: Use the DATEDIFF() function.
Your COUNT(min) counts the number of rows where min IS NOT NULL. You may as well say COUNT(*). But did you really want to count the number of rows?

how to change the year of birth to age in .sql?

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

SQL division by a time frame

Have an RDB with a quantity x and the date that quantity started being tracked, date_1 and the date it was finished being tracked date_2. If tracking is still on going that second date is NULL obviously.
What I would like to do is take the number X and get its average over either date_1 and date_2. And if date_2 is NULL then go by current time. Any help?
[EDIT] to clarify in RDB format, one row with data column (x), data column (date_1) and data column (data_2) along with other fields of importance.
[EDIT] so imagine X as some integer like 100,000 and dates being March 30, 2016 12:29:45 and April 3, 2016 03:42:29. Not sure how to breakdown the date/times yet so open to suggestions. The end goal is calculate how much of x can be allocated in one month vs how much in the other month. Depending on how fine grain you breakdown the time frame (days vs seconds) will ultimately change those numbers.

SQL Query to get data between two weeks?

I have a week column with week numbers as w0, w1, w2.... I am trying to get last last six weeks data. Here's the sql query I am using.
SELECT * FROM week
WHERE uid = '9df984da-4318-1035-9589-493e89385fad'
AND report_week BETWEEN `'w52' AND 'w5'`;
'w52' is essentially week 52 in December 2015 and 'w5' is Jan 2016. The 'between' seems to not work. Whats the best way to get data from the above two weeks?
Here's the CREATE TABLE statement:
CREATE TABLE `week` (`uid` VARCHAR(255) DEFAULT '' NOT NULL,
`report_week` VARCHAR(7) NOT NULL,
`report_files_active` BIGINT DEFAULT NULL);
Essentially this table is getting populated from other table which has date column. It uses dates from other table and summarizes weekly data into this.
Any help is appreciated.
Refer to this SO Discussion which details the reasons for a problem similar to yours.
BETWEEN 'a' and 'b' actually matches to columnValue >='a' and columnValue <= 'b'
In your case w52 is greater than w5 due to lexicographic ordering of Strings - this means that the BETWEEN clause will never return a true (think about it as equivalent to saying BETWEEN 10 and 1 instead of BETWEEN 1 and 10.
Edit to my response:
Refrain from storing the week value as a string. Instead here are a couple of approaches in order of their preference:
Have a timestamp column. You can easily then use MySQL query
facilities to extract the week information out of this. For a
reference see this post.
Maintain two columns - YEAR, WEEKNO where YEAR will store values
like 2015, 2016 etc and WEEKNO will store the week number.
This way you can query data for any week in any year.
please show me table structure and DB name because it different for other, if it is any timestamp then we can use BETWEEN 'systemdate' AND 'systemdate-6'

What column type to use for storing a `date` that may leave out month and day?

I am trying to add a new column collect_date in a table, so that users can specify when they collected an object.
Considering that not every user can recall the exact collect_date, I would offer them an option to specify year or year/month only, leaving out parts that they can't recall.
Possible queries on collect_date:
order by collect_date desc
range, eg. month between 1 and 3
What is a suitable column type for this kind of data in MySQL?