I have a column with multiple values including date of births and year of births
ID OptionValue
1 1992
2 1993-05-31
3 2002
4 1976-06-3
Ideally I want the solution to be
ID OptionValue Age
1 1992 31
2 1993-05-31 29
3 2002 21
4 1976-06-3 46
now
Select TIMESTAMPDIFF(YEAR, lp.optionValue , CURDATE())as Age from learner
and
Select DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(lp.optionValue , '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(lp.optionValue, '00-%m-%d')) as Age from learner
works perfectly well for me when the date format is 'yyyy-mm-dd' but throws an error for when the year is given only. Can I calculate the age from just given year?
Here is a trick:
Select TIMESTAMPDIFF(YEAR, if(length(lp.optionValue) = 4 , concat(lp.optionValue ,'/01/01'),lp.optionValue), CURDATE())as Age from learner
Related
I have a MySQL requirement to select data from a table based on a start date and end date and group it by weekly also selecting the data in reverse order by date. Assume that, I have chosen the start date as 1st November and the end date as 04 December. Now, I would like to fetch the data as 04 December to 28 November, 27 November to 20 November, 19 November to 12 November and so on and sum the value count for that week.
Given an example table,
id
value
created_at
1
10
2021-10-11
2
13
2021-10-17
3
11
2021-10-25
4
8
2021-11-01
5
1
2021-11-10
6
4
2021-11-18
7
34
2021-11-25
8
17
2021-12-04
Now the result should be like 2021-12-04 to 2021-11-28 as one week, following the same in reverse order and summing the column value data for that week. I have tried in the query to add the interval of 7 days after the end date but it didn't work.
SELECT count(value) AS total, MIN(R.created_at)
FROM data_table AS D
WHERE D.created_at BETWEEN '2021-11-01' AND '2021-12-04' - INTERVAL 7 DAY ORDER BY D.created_at;
And it's also possible to have the last week may have lesser than 7 days.
Expected output:
end_interval
start_interval
total
2021-12-04
2021-11-27
17
2021-11-27
2021-11-20
34
2021-11-20
2021-11-13
4
2021-11-13
2021-11-06
1
2021-11-06
2021-10-30
8
2021-10-30
2021-10-25
11
Note that the last week is only 5 days depending upon the selected from and end dates.
One option to address this problem is to
generate a calendar of all your intervals, beginning from last date till first date, with a split of your choice, using a recursive query
joining back the calendar with the original table
capping start_interval at your start_date value
aggregating values for each interval
You can have three variables to be set, to customize your date intervals and position:
SET #start_date = DATE('2021-10-25');
SET #end_date = DATE('2021-12-04');
SET #interval_days = 7;
Then use the following query, as already described:
WITH RECURSIVE cte AS (
SELECT #end_date AS end_interval,
DATE_SUB(#end_date, INTERVAL #interval_days DAY) AS start_interval
UNION ALL
SELECT start_interval AS end_interval,
GREATEST(DATE(#start_date), DATE_SUB(start_interval, INTERVAL #interval_days DAY)) AS start_interval
FROM cte
WHERE start_interval > #start_date
)
SELECT end_interval, start_interval, SUM(_value) AS total
FROM cte
LEFT JOIN tab
ON tab.created_at BETWEEN start_interval AND end_interval
GROUP BY end_interval, start_interval
Check the demo here.
i'm trying to run mysql query for average vacation hours and sick leaves for the employees that were born
• Between the years 1960 and 1969
• Between the years 1970 and 1979
• Between the years 1980 and 1989
SELECT AVG(VacationHours), AVG(SickLeaveHours)
FROM HumanResources.employee
WHERE BirthDate BETWEEN '1960-1-1' AND '1969-12-31'
OR BirthDate BETWEEN '1970-1-1' AND '1979-12-31'
OR BirthDate BETWEEN '1980-1-1' AND '1980-12-31'
Output
44 49
I want output for individual decade.
something like this.
Output
44 49
44 43
42 47
You can simplify like this when the years are continuous
SELECT Extract(YEAR FROM BirthDate) ,
Avg(VacationHours),
Avg(SickLeaveHours)
FROM HumanResources.employee
WHERE BirthDate BETWEEN '1960-1-1' AND '1980-12-31'
GROUP BY Extract(YEAR FROM BirthDate)
Use GROUP BY with CASE:
SELECT (CASE WHEN BirthDate BETWEEN '1960-01-01' AND '1969-12-31' THEN '1960s'
WHEN BirthDate BETWEEN '1970-01-01' AND '1979-12-31' THEN '1970s'
WHEN BirthDate BETWEEN '1980-01-01' AND '1980-12-31' THEN '1980s'
END) as decade,
AVG(VacationHours), AVG(SickLeaveHours)
FROM HumanResources.employee
WHERE BirthDate >= '1960-01-01' AND BirthDate < '1990-01-01'
GROUP BY decade
ORDER BY decade;
MySQL permits you to use a column alias for GROUP BY. Some databases require that you repeat the expression.
Suppose I want to find all of the records involved in June!
-----------------------------------------------------------
CaseID StartDate EndDate
1 2016-05-31 2016-06-01
2 2016-02-29 2016-06-20
3 2016-03-21 2016-06-01
4 2016-05-05 2016-06-01
5 2016-05-20 2016-07-01
6 2016-05-12 2016-12-31
SELECT CaseID, StartDate, EndDate
FROM ServiceCase
WHERE((StartDate > '2016-05-31' and StartDate < '2016-07-01') or (EndDate >
'2016-05-31' and EndDate < '2016-07-01'))
But I cannot search CaseID 6's Record, Am I Logic wrong?
It seems like you want to select all cases that were in progress during the month of June. If so, then these are the 4 possible scenarios:
Or, in other words, the cases would have to both
start before July; and
end after May
So, the query would essentially look like this:
SELECT CaseID, StartDate, EndDate
FROM ServiceCase
WHERE
StartDate < '2016-07-01' AND EndDate > '2016-05-31'
Output: SQL fiddle
Try as mentioned below:
SELECT CaseID, StartDate, EndDate
FROM ServiceCase
WHERE(StartDate < '2016-07-01' and EndDate > '2016-05-31')
You could try MySQL MONTH() Function; sample code as bellow for the month June
SELECT CaseID, StartDate, EndDate
FROM ServiceCase
WHERE MONTH(StartDate) = 6
OR MONTH(EndDate) = 6
OR (MONTH(StartDate) < 6 AND MONTH(EndDate) > 6)
Note: this is just an option to compare month part without considering performance.
I have bellow snippet table format.
Table name:- wp_lead_count_freevendor
id entryid start_date end_date user_id count_set entry_date cancel_set_date
70 11392 2015-12-03 2015-12-03 3185 1 2015-12-03 2015-12-04
71 11393 2015-12-03 2015-12-03 3185 1 2015-12-03 2015-12-04
72 11394 2014-10-01 2014-10-01 3185 1 2014-10-01 2014-10-01
Here i want to calculate count total count_set column. of current month & year by start_date column WHERE user_id=3185.
suppose in start_date current year is 2015 & current month is 12:-
year month count total
2015 12 2
For user id 3185 of this month of year count_set total =2
so any body will tell how do i fire the query to get count_set total for current year of current month for user_id=3185.
I have tried bellow query but its not working.
$check_per_month=mysql_query("SELECT DATE_FORMAT(end_date, '%Y') as 'year',
DATE_FORMAT(end_date, '%m') as 'month',
COUNT(id) as 'total'
FROM wp_lead_count_freevendor WHERE user_id=$wp_lead_count_user_id
GROUP BY DATE_FORMAT(end_date, '%Y%m')") OR DIE(mysql_error());
while($row = mysql_fetch_assoc($check_per_month))
{
echo $sql_chk_current_month_count=$row['total'];
}
Try to count using the where , year and month methods like this:
SELECT .... WHERE YEAR(start_date)=2015 AND MONTH(start_date)=12
Try this query:
SELECT YEAR(NOW()) as `year`,MONTH(NOW()) as `month', SUM(count_set) as `count_set`
From wp_lead_count_freevendor
WHERE YEAR(start_date)=YEAR(NOW()) AND MONTH(start_date)=MONTH(NOW()) AND user_id=3185
group by YEAR(NOW()),MONTH(NOW())
I have the following table (simplified):
user_id date hours
1 2012-03-01 5
2 2012-03-01 8
3 2012-03-01 6
1 2012-03-02 3
3 2012-03-02 7
What I want is to get the the sum of hours worked for a given user id (ex. 1), and the total hours worked regardless of what user (for a given time period) in a single query.
So for user_id = 1, and time period: 2012-03-01 - 2012-03-02 the query should return: own=8, total=29.
I can do it in two separate queries, but not in a single one.
Use CASE:
SELECT SUM(
CASE user_id
WHEN 1 THEN hours
ELSE 0
END) as Own,
SUM(hours) as Total
FROM HoursWorked
WHERE date BETWEEN '2012-03-01' AND '2012-03-02';
I think I have something that works using the following schema:
CREATE TABLE hoursWorked
(
id int,
date date,
hours int
);
INSERT INTO hoursWorked
(id, date, hours)
VALUES
('1','2012-03-01','5'),
('2','2012-03-01','8'),
('3','2012-03-01','6'),
('1','2012-03-02','3'),
('3','2012-03-02','7');
And this query:
select parent.id, parent.date, parent.hours, (select sum(hours)
from hoursWorked child
where child.id = parent.id) as totalHours
from hoursWorked parent
I was able to get these results:
ID DATE HOURS TOTALHOURS
1 March, 01 2012 00:00:00-0800 5 8
2 March, 01 2012 00:00:00-0800 8 8
3 March, 01 2012 00:00:00-0800 6 13
1 March, 02 2012 00:00:00-0800 3 8
3 March, 02 2012 00:00:00-0800 7 13
Diego's answer albeit procedural is a great way to get the answer you are looking for. Of course for your date range you would need to add a WHERE date BETWEEN 'startdate' AND 'enddate'. The dates need to be in a format that mysql recognizes, typically 'yyyy-mm-dd'
Another solution that doesn't get you the results in one row, but in a result set would be to do a UNION
SELECT user_id, SUM(hours) as hours FROM table WHERE date BETWEEN 'startdate' AND 'enddate' WHERE user_id = 3
UNION
SELECT null as user_id, SUM(hours) as hours FROM table WHERE date BETWEEN 'startdate' AND 'enddate'