How to create group by age employee in php myqsl - mysql

I want to create chart.js for avarage age in my company. But I can't create the query.
SELECT DATEDIFF(CURRENT_DATE, STR_TO_DATE(t.employee_birthday, '%Y-%m-%d'))/365 AS `ageInYears`
FROM `employee` `t`
WHERE `employee_birthday` BETWEEN `employee_birthday` = 20 and `employee_birthday` = 30

Presumably, employee_birthday is actually a date. At last that would make sense to me.
If you want employees between 20 and 30, then the logic is something like this:
WHERE employee_birthday >= CURDATE() - INTERVAL 30 YEAR AND
employee_birthday < CURDATE() - INTERVAL 20 YEAR

I am not sure why you are not able to use ageInYears in comparison but you will able to get the result using the following query
SELECT DATEDIFF(CURRENT_DATE, STR_TO_DATE(t.employee_birthday, '%Y-%m-%d'))/365 AS ageInYears
FROM user t where t.employee_birthday != '' and DATEDIFF(CURRENT_DATE, STR_TO_DATE(t.employee_birthday, '%Y-%m-%d'))/365 between 30 and 40

Related

How to select last 7 days available - MySql

I am having problem with dealing with data in MySQL. How can I select all data from the pasty seven available data?
I tried to run
SELECT * FROM database where ship_day
BETWEEN DATE_SUB(NOW(), INTERVAL 7 DAY) AND NOW();
but I doesn't work for my purpose.
Let's say we are on January, 9th and my MAX(ship_day) is January, 7th and I want to pull data from the past 7 available data so from January 1st to 7th.
I tried to run
SELECT * FROM database where ship_day
BETWEEN DATE_SUB(MAX(ship_day), INTERVAL 7 DAY) AND MAX(ship_day);
but I got an error.
I know that I can increase INTERVAL 7 DAY to INTERVAL 9 DAY but I want this process to be automatic. How can I solve?
Well, here is one method:
SELECT d.*
FROM database d
WHERE d.ship_day >= COALESCE( (SELECT DISTINCT d2.ship_day
FROM database d2
ORDER BY d2.ship_day DESC
LIMIT 1 OFFSET 6
), d.ship_day
);
Note: If you have only one row per ship_day, then just use limit:
SELECT d.*
FROM database d
ORDER BY d.ship_day DESC
LIMIT 7
Let's say we are on January, 9th and my MAX(ship_day) is January, 7th
and I want to pull data from the past 7 available data so from January
1st to 7th.
I assume you are looking for the query below but hard to say for sure without example data and expected results.
SELECT
*
FROM
t
WHERE
ship_day >= (
SELECT
MAX(ship_day) - INTERVAL 7 DAY
FROM
t
)
Or you can also write this as
SELECT
*
FROM
t
WHERE
ship_day >= (
SELECT
MAX(ship_day)
FROM
t
) - INTERVAL 7 DAY
You can get the last date for which you have data with:
select MAX(ship_day) FROM database
so use it like this:
SELECT * FROM database
where ship_day >= DATE_SUB((select MAX(ship_day) FROM database), INTERVAL 7 DAY)

SQL select by date from today

I'm studying SQL (Using MariaDB 10.2) and I'm using a huge example database I found online. It has an 'employees' table, and this one has a 'birth_date' column of 'date' type. I want to select all those employees who are more than 50 years old, for example, or maybe those who will be 25 years old on an specific date . Is there a way to do something like this?
You can add or subtract intervals to dates:
SELECT *
FROM employee
WHERE birth_date <= NOW() - INTERVAL 50 YEAR
Assuming t-sql, then for those over 50 today, use:
select * from employees where datediff(year, birth_date, now()) > 50
For those who will be 25 on a certain date use:
select * from employees where datediff(year, birthdate, certain_date) = 25
Use this
SELECT * FROM myTable WHERE DATE(myDate) = DATE(NOW())
This is for MySql DB
You can use INTERVAL function which you can add or subtract Dates:
SELECT * FROM employee WHERE birth_date <= (NOW() - INTERVAL 50 YEAR);
NOW() -----> Present Date
-INTERVAL 50 YEAR -----> Subtract that Date to 50 Years

mysql optimize query where date hour

Hi all, I have pretty awfull query, that needs optimizing.
I need to select all records where date of created matches NOW - 35days, but the minutes and seconds can be any.
So I have this query here, its ugly, but working:
Any optimisation tips are welcome!
SELECT * FROM outbound_email
oe
INNER JOIN (SELECT `issue_id` FROM `issues` WHERE 1 ORDER BY year DESC, NUM DESC LIMIT 0,5) as issues
ON oe.issue_id = issues.issue_id
WHERE
year(created) = year( DATE_SUB(NOW(), INTERVAL 35 DAY) ) AND
month(created) = month( DATE_SUB(NOW(), INTERVAL 35 DAY) ) AND
day(created) = day( DATE_SUB(NOW(), INTERVAL 35 DAY) ) AND
hour(created) = hour( DATE_SUB(NOW(), INTERVAL 35 DAY) )
AND campaign_id IN (SELECT id FROM campaigns WHERE initial = 1)
I assume the field "created" is a datetime field and is from the issues table? Since you don't need anything else on the issues and campaign table, then you can do the following:
SELECT e.* FROM outbound_email e
JOIN issues i ON e.issue_id = i.issue_id
JOIN campaigns c ON c.id = i.campaign_id
WHERE i.created < DATE_SUB(NOW(), INTERVAL 35 DAY)
AND c.initial = 1
There's no need to separate the datetime field into years, months...etc.
You seem to be saying you want to select all rows from a table where the time they were created was the same hour as it is currently, 35 days ago
SELECT * FROM table WHERE created BETWEEN
DATE_ADD(CURDATE(), INTERVAL (HOUR(now()) - 840) HOUR) AND
DATE_ADD(CURDATE(), INTERVAL (HOUR(now()) - 839) HOUR)
Why does it work? Curdate gives us today at midnight. We add to this the current hour of the time (e.g. Suppose it's now 5pm we'd add `HOUR(NOW()) which would give us 17, for a time now of 5pm) but we also subtract 840 because that's 35 days * 24 hours a day = 840 hours. Date add will hence add -823 hours to the current date, i.e. 5pm 35 days ago
We make the search a range to get all the records from the hour, the simplest way to specify an hour later is to subtract 839 hours instead of 840
Technically this query will also return records that are bang on 6pm (but not a second later) 35 days ago too because between is inclusive (between 1 and 10 will return 10 also
If this is a problem, change the BETWEEN for created >= blah AND created < blahblah
I haven't put the rest of your query in for reasons of clarity
As a side note, the way you did it wasn't bad- you could have simplified things by not having the year/month/day parts, just dropping the time part of the date with date(created) = date_sub(curdate(), interval 35 day) which is the year month and day combined as a date, no time element.. BUT it is generally always best to leave table data alone rather than format or convert it just to match a query. If you convert table data then indexes can no longer be used. If you go the extra mile to get your query parameters into the format of the column, and don't convert the table data then indexes on the column can be used

MySQL COUNT for days

I want to get the value of users visiting my page for 10 days in a chart. I need to COUNT() all the values from the last ten days.
The best layout would be
Day|COUNT(ip)
1 - 10
2 - 12
3 - 52
......
I hope you understand what I mean.
Can MySQL do this directly or need I to do this in PHP in 10 seperate querys?
Regards,
Moritz
Update with Tablestructure:
Id (Auto Increment)|Time (Unix Timestamp)|Ip|Referer
This should run fast for you
SELECT COUNT(ip) ipcount,dt FROM
(
SELECT ip,DATE(FROM_UNIXTIME(`Time`)) as dt FROM mytable
WHERE `Time` > TO_UNIXTIME(NOW() - INTERVAL 10 DAY)
) A GROUP BY dt;
Make sure you have an index on Time
ALTER TABLE mytable ADD INDEX TimeIndex (`Time`);
This will give you results with actual date values:
SELECT
COUNT(DISTINCT ip),
FROM_UNIXTIME(Time, '%m/%d/%Y') AS Day
FROM
tbl
WHERE
Time >= UNIX_TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL -10 DAY))
GROUP BY
FROM_UNIXTIME(Time, '%m/%d/%Y')
try this:
SELECT CAST(DATE(FROM_UNIXTIME(`Time`)) AS CHAR) as dateoftime, COUNT(Ip) as cnt
FROM tablename
WHERE DATE(FROM_UNIXTIME(`Time`)) > DATE_SUB(current_timestamp, INTERVAL 10 DAY)
GROUP BY CAST(DATE(FROM_UNIXTIME(`Time`)) AS CHAR)

Rolling 30 day uniques in sql

Suppose you have a table of the form:
create table user_activity (
user_id int not null,
activity_date timestamp not null,
...);
It's easy enough to select the number of unique user_id's in the past 30 days.
select count(distinct user_id) from user_activity where activity_date > now() - interval 30 day;
But how can you select the number of unique user_ids in the prior 30 days for each of the past 30 days? E.g. uniques for 0-30 days ago, 1-31 days ago, 2-32 days ago and so on to 30-60 days ago.
The database engine is mysql if it matters
You could try using a sub query:
SELECT DISTINCT `activity_date` as `day`, (
SELECT count(DISTINCT `user_id`) FROM `user_activity` WHERE `activity_date` = `day`
) as `num_uniques`
FROM `user_activity`
WHERE `activity_date` > NOW() - INTERVAL 30 day;
This should give you the number of unique users for each day. However, I haven't tested this since I don't have the DB to work with.
I haven't tried this in MySQL, but hopefully the syntax is right. If not, maybe it will point you in the right direction. First, I often employ a Numbers table. It can be a physical table simply made up of numbers or it can be a generated/virtual/temporary table.
SELECT
N.number,
COUNT(DISTINCT UA.user_id)
FROM
Numbers N
INNER JOIN User_Activity UA ON
UA.activity_date > NOW() - INTERVAL 30 + N.number DAY AND
UA.activity_date <= NOW() - INTERVAL N.number DAY
WHERE
N.number BETWEEN 0 AND 30
GROUP BY
N.number
I'm not familiar with the whole INTERVAL syntax, so if I got that wrong, please let me know and I'll try to correct it.
If you get the days number for todays date and mod it by 30 you get the offset of the current day. Then you add that to each number for a date and divide the result by 30, this gives you the group of days. Then group your results by this number. So in code something like this:
select count(distinct user_id), (to_days(activity_date)+(to_days(now()) % 30)) / 30 as period
from user_activity
group by (to_days(activity_date)+(to_days(now()) % 30)) / 30
I will leave calculating the reverse numbering of period up to you (hint: take the period number for the current date as "max" and subtract period above and add 1.)