mySQL Populate DB Column using calculated value from anouther table - mysql

What I am trying to do is have a field called 'age' autopopulate from a persons date of birth when a row is added - the trick is the persons date of birth resides in anouther field.
My two tables are:
student
student_id (PK), first_name, last_name, date_of_birth
fitness_report
report_id (PK), test_date, test_period, age_tested, student_id (FK)
ideally the age_tested will be caluclated from the test_period however happy to use ()NOW as that'll be within reasonable limits.
Obviously what i need to do here is create a trigger - but not sure on the SELECT statement to get the age to populate. Help is much appreciated.

As rwilliams said, it is not advisable to store the age_tested as it is redundant but if it is what you want to do you can wrap a simple trigger around Mosty's solution -
CREATE TRIGGER fitness_report_insert BEFORE INSERT ON `fitness_report`
FOR EACH ROW
BEGIN
SET NEW.age_tested = (SELECT DATE_FORMAT(NEW.test_period, '%Y') - DATE_FORMAT(student.date_of_birth, '%Y') - (DATE_FORMAT(NEW.test_period, '00-%m-%d') < DATE_FORMAT(student.date_of_birth, '00-%m-%d')) FROM student WHERE student.student_id = NEW.student_id);
END
This assumes that test_period is a date as previously mentioned by Mosty. I have not tried this as I do not have access to a server right now so it may need a little tweaking.
UPDATE: You could try the following as a starting point for your stats -
SELECT
DATE_FORMAT(test_period, '%Y') - DATE_FORMAT(date_of_birth, '%Y') - (DATE_FORMAT(test_period, '00-%m-%d') < DATE_FORMAT(date_of_birth, '00-%m-%d')) AS age,
s.gender,
AVG(r.score) AS score
FROM student s
INNER JOIN fitness_report r
ON s.student_id = r.student_id
GROUP BY age, s.gender

This is how to get current age:
select s.name, s.date_of_birth,
date_format(now(), '%Y') - date_format(date_of_birth, '%Y') -
(date_format(now(), '00-%m-%d') < date_format(date_of_birth, '00-%m-%d'))
as age
from s
Example
This is how to get age up to the test_period (shouldn't it be test_date?):
select s.name, s.date_of_birth, r.test_period,
date_format(test_period, '%Y') - date_format(date_of_birth, '%Y') -
(date_format(test_period, '00-%m-%d') < date_format(date_of_birth, '00-%m-%d'))
as age
from r
join s on s.id_student = r.student_id
Example

Related

How to get user details between two ages from dob without age column mysql

I want to get details of the user between two ages from date of birth. My conditions are,
Calculate the age from DOB
Find the user details between two ages
My tables is,
id username phone dob
-------------------------------------
1 Jithin 123456 31/12/1990
2 Binoy 235612 12/12/1991
3 Jibin 353453 12/12/1996
I have create mysql query as below
SELECT username, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age FROM tbl_user WHERE age BETWEEN 20 AND 30
But the above code shows an error the column age not found. How to fix this problem. Any alternate way to find age from dob and compare it.
It does not work because you can't use an alias right away. Use a subquery around it or repeat the calculation. There is a shorter way to calculate it:
SELECT TIMESTAMPDIFF(YEAR, dob, CURDATE()) AS age
from tbl_user
where TIMESTAMPDIFF(YEAR, dob, CURDATE()) between 20 and 30
You could use subquery:
SELECT *
FROM (SELECT username,
DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') -
(DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age
FROM tbl_user) sub
WHERE sub.age BETWEEN 20 AND 30;
Column age from SELECT clause is not visible in WHERE at the same level. You could either wrap it with subquery or repeat entire expression.

MySQL calculating age based on birthDate

I am trying to calculate the age based on the birthDate in MySQL using SQL statement.
My birthDate was varchar() and in this format: 29/11/1994 (DD/MM/YYYY).
My SQL statement:
SELECT DATEDIFF(YY, birthDate, GetDate()) AS Age
FROM bookedevent be INNER JOIN account a
ON be.bookedEventBY = a.accountName WHERE a.accountID = 1
However, when I test in MySQL workbench, I am getting this error message: Incorrect parameter count in the call DATEDIFF.
ANy guides?
Thanks in advance.
You are using SQL Server syntax in MySQL. That won't work. You can use TIMESTAMPDIFF():
SELECT TIMESTAMPDIFF(YEAR, birthDate, CURDATE()) AS Age
FROM bookedevent be INNER JOIN
account a
ON be.bookedEventBY = a.accountName
WHERE a.accountID = 1;
Note that the semantics for TIMESTAMPDIFF() are different than for DATEDIFF() in SQL Server. However, TIMESTAMPDIFF() is probably closer to what you really want.
Use this code
SELECT DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(birthDate, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(birthDate, '00-%m-%d')) AS age
FROM bookedevent be INNER JOIN
account a
ON be.bookedEventBY = a.accountName
WHERE a.accountID = 1;

Update age column in MySQL

I have a user table with the user's birthday (YYYY-MM-DD) as well as age. I want to run a script to calculate and update the age column nightly via cron.
This SQL works well for selecting and calculating the age:
SELECT
DATE_FORMAT(NOW(), '%Y') -
DATE_FORMAT(`birthday`, '%Y') -
(DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(`birthday`, '00-%m-%d')) AS age
FROM
`jos_jcourse_students`
But is it possible to update the age column with a single statement? Tried the following, but all I managed to do was populate the age column with all 0s! Do I need to use some sort of MySQL loop?
UPDATE
`jos_jcourse_students`
SET
age = "SELECT DATE_FORMAT(NOW(), '%Y') -
DATE_FORMAT(`birthday`, '%Y') -
(DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(`birthday`, '00-%m-%d')) AS age
FROM
`jos_jcourse_students`"
UPDATE `jos_jcourse_students`
SET age = DATE_FORMAT(FROM_DAYS(TO_DAYS(NOW())-TO_DAYS(birthday)), '%Y')+0
OR according to your logic it will be
UPDATE `jos_jcourse_students`
SET age =((DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(`birthday`, '%Y')) -
(DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(`birthday`, '00-%m-%d')))
UPDATE
`jos_jcourse_students`
SET
age = (SELECT DATE_FORMAT(NOW(), '%Y') -
DATE_FORMAT(`birthday`, '%Y') -
(DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(`birthday`, '00-%m-%d')) AS age
FROM
`jos_jcourse_students`)
One way you can achieve the above result by using the self join technique. i.e join to the same table using its unique id (primary key example studentId)
UPDATE jos_jcourse_students a,
( SELECT studentId, DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(`birthday`, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(`birthday`, '00-%m-%d')) AS age
FROM `jos_jcourse_students`) b
SET a.age = b.age
WHERE a.studentId = b.studentId
Note: studentId is primary key in jos_jcourse_students

mysql join only return one result from the join

I have the following query,
SELECT `candidates`.`candidate_id`,
`candidates`.`first_name`,
`candidates`.`surname`,
`candidates`.`DOB`,
`candidates`.`gender`,
`candidates`.`talent`,
`candidates`.`location`,
`candidates`.`availability`,
DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(`candidates`.`DOB`, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(`candidates`.`DOB`, '00-%m-%d')) as `age`,
`candidate_assets`.`url`,
`candidate_assets`.`asset_size`
FROM `candidates`
LEFT JOIN `candidate_assets` ON `candidate_assets`.`candidates_candidate_id` = `candidates`.`candidate_id`
WHERE `candidates`.`availability` = 'yes'";
The query is currently returning multiple rows from the joined table is possible to return only one result per join?
It is possible. Try to use GROUP_CONCAT function, e.g. -
SELECT
c.`candidate_id`,
c.`first_name`,
c.`surname`,
c.`DOB`,
c.`gender`,
c.`talent`,
c.`location`,
c.`availability`,
DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(c.`DOB`, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(c.`DOB`, '00-%m-%d')) as `age`,
GROUP_CONCAT(ca.`url`) `url`,
GROUP_CONCAT(ca.`asset_size`) `asset_size`
FROM `candidates` c
LEFT JOIN `candidate_assets` ca ON ca.`candidates_candidate_id` = c.`candidate_id`
WHERE c.`availability` = 'yes'
GROUP BY c.candidate_id

How to group number of users by age bands in mysql

Essentially I have a mysql database with users and their corresponding date of birth. I have also found the following bit of code that would help me find the users actual age from the date of birth. Finding date of birth What I need to do is find different "age bands" and count the amount of users in that age band. I have also found this example that shows exactly how to group this data. I want to calculate the age first and use it in the a way similar as shown in the following link. I have written the following code and am getting an error when running it:
SELECT DATE_FORMAT(NOW(), '%Y') -
DATE_FORMAT(data_of_birth, '%Y') -
(DATE_FORMAT(NOW(), '00-%m-%d') <
DATE_FORMAT(data_of_birth,
'00-%m-%d')) AS age, COUNT(*),
CASE
WHEN age >= 10 AND age <= 20 THEN '10-20'
WHEN age >=21 AND age <=30 THEN '21-30'
WHEN age >=31 AND age <=40 THEN '31-40'
WHEN age >=41 AND age <= 50 THEN '31-40'
WHEN age >=51 AND age <=60 THEN '51-60'
WHEN age >=61 THEN '61+'
END AS ageband
.. ..
GROUP BY ageband
I get an error stating that the field age is not known. Am I writing this incorrectly? I could easily write the whole block of code that calculates age where age is written in the case statement but this seems to be very inefficient. I am not very good at mysql (yet) and I know that there has to be a better way to do this. I guess my main question is if there is some sort of way to create a function inside a query and assign the output of that function to a value?
In this case you can use a subquery:
SELECT
COUNT(*),
CASE
WHEN age >=10 AND age <=20 THEN '10-20'
WHEN age >=21 AND age <=30 THEN '21-30'
WHEN age >=31 AND age <=40 THEN '31-40'
WHEN age >=41 AND age <=50 THEN '41-50'
WHEN age >=51 AND age <=60 THEN '51-60'
WHEN age >=61 THEN '61+'
END AS ageband
FROM
(
DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(date_of_birth, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(date_of_birth, '00-%m-%d')) AS age,
.. ..
) as tbl
GROUP BY ageband;
So first it executes the subquery and builds a table of ages, than it aggregates the age value.