I am calculating the age of my users in MySQL and I am running into a little problem. I am able to successfully calculate the age of each user, however, when I try to count the number of users who are part of each age group, that is when I run into trouble. Here is my query:
SELECT COUNT(user_id) AS "Number of Users",
YEAR(CURDATE()) -
YEAR(STR_TO_DATE(birth_date, '%m/%d/%Y')) -
(RIGHT(CURDATE(), 5) < RIGHT(STR_TO_DATE(birth_date, '%m/%d/%Y'), 5))
AS Age
FROM user
GROUP BY Age
I feel like I am close, it just is not working for me. How would I count the number of users in each age group?
You need a subquery to access calculated column aliased Age in Group By clause
SELECT Age,COUNT(user_id) AS "Number of Users"
FROM
(
SELECT userid,
YEAR(CURDATE()) -
YEAR(STR_TO_DATE(birth_date, '%m/%d/%Y')) -
(RIGHT(CURDATE(), 5) < RIGHT(STR_TO_DATE(birth_date, '%m/%d/%Y'), 5))
AS Age
FROM user
) as Z
GROUP BY Age
Related
Hi there I want to design this query in mySQL.
Statement: For all the customers that transacted during 2017, what % made another transaction within 30 days?
can you tell me how such query can be designed?
This is the picture of the table to perform this query on:
Table name is: transactions
Just use lead() to get the next date. Then aggregate at the customer level to determine if any transaction in the time period has another within 30 days for that customer.
Finally, aggregate again:
select avg(case when mindiff < 30 then 1.0 else 0 end) as within_30days
from (select customerid, min(datediff(next_date - date)) as mindiff
from (select t.*, lead(date) over (partition by customerid order by date) as next_date
from transactions t
) t
where date >= '2017-01-01' and date < '2018-01-01'
group by customerid
) c
Basically I have a table like this:
Table Time:
ID.......Date
1......08/26/2016
1......08/26/2016
2......05/29/2016
3......06/22/2016
4......08/26/2015
5......05/23/2015
5......05/23/2015
6......08/26/2014
7......04/26/2014
8......08/26/2013
9......03/26/2013
The query should return like this
Year........CountNum
2016........4
2015........3
To find out which year does its value tend to increase in. I notice that I want to display the years that have more values (number of row in this case) than the previous year.
What I've done so far
SELECT Year, count(*) as CountNum
FROM Time
GROUP BY Year
ORDER BY CountNum DESC;
I don't know how to get the year from date format. I tried year(Date) function, but I got Null data.
Please help!
It should works fine.
select year(date), count(*) as countNum
from time
group by year(date)
order by countNum
Join the grouped data to itself with 1 year offset:
select
a.*
from
(
select year(`Date`) as _year, count(*) as _n
from time group by 1
) a
left join
(
select year(`Date`) as _year, count(*) as _n
from time group by 1
) b
on a._year = b._year-1
where a._n > b._n
order by 1
I need to create a query that looks like this image with the result:
You can ignore the names of the user, user_id is fine for now. Each user can have several timesheets for one day. So I need to count the hours and place it in its own column for day of the week. Then have a total at the end. Here is a screen shot of the database:
Here is what I have so far that gets me the days of the week totals but not grouped in one record with the day of the week as its own column and a total. Any help would be appreciated. Thanks!
SELECT user_id, WEEKDAY(start_date) AS day, (select time_to_sec(timediff(end_date, start_date )) / 3600) AS hours FROM `timesheet_table` WHERE id > 0 GROUP BY day, user_id
If you need a totat you can use a sum and group by
In Group by you can't use the alias but you should use the expression
SELECT
user_id
, WEEKDAY(start_date) AS day
, sum((select time_to_sec(timediff(end_date, start_date )) / 3600)) AS hours
FROM `timesheet_table`
WHERE id > 0
GROUP BY WEEKDAY(start_date), user_id
E.g.:
SELECT user_id
, DATE(start_date) dt
, SEC_TO_TIME(SUM(TIME_TO_SEC(end_date)-TIME_TO_SEC(start_date))) day_total
-- [or , SUM(TIME_TO_SEC(end_date)-TIME_TO_SEC(start_date))/3600 day_total]
FROM my_table
WHERE start_date BETWEEN '2016-10-01 00:00:00' AND '2016-10-07 23:59:59'
GROUP
BY user_id
, DATE(start_date);
The rest of the problem (missing days, display issues, weekly totals, etc.) would normally be handled in application level code.
I have a simple MySQL db listing the total time spent each user has spent online in seconds (just a string) per day. I would like to select the top 10% of those users for a given day and return there usernames.
Is there a way to do this in MySQL in a single query..? I've seen examples where you select the top 10 users, but not based on a percentage of total users...
Hope this will help you
I used CURRENT_DATE to limit search.
SELECT user_id, date, total_time FROM
(
SELECT user_id, #rownum:=#rownum+1 AS rownum
FROM TABLE_USER , (SELECT #rownum:=0) R
WHERE date = CURRENT_DATE
ORDER by total_time desc
) temp
where rownum < (select count(*) from TABLE_USER where date = CURRENT_DATE) / 10
try this
SELECT 0.1 * count(username) as percented_users FROM prices
GROUP BY username
You may try this way:
select * from table limit floor((select count(1) from table)*0.1)
I have this query to show a list of trending (most searched) names on my website:
SELECT name, COUNT(*) AS total_trends
FROM trending_names
WHERE dateTime BETWEEN '"&fromDate&"' AND '"&toDate&"' // -7 days to Now()
GROUP BY name
ORDER BY COUNT(*) DESC
LIMIT 10;
...and this is the kind of results I'm printing to screen:
(numbers represent quantity of searches made)
Angelina Jolie 31,293
Rihanna 26,722
Lindsay Lohan 18,351
Brad Pitt 11,901
I would now like to change the numbers to percentages; so I really need to be getting the total count of all trending names within the last 7 days, to calculate the correct percentage.
Is there a way I can add a total count to this query, without adding an additional query?
You can do in single query :
Try Below :
SELECT name, COUNT(*) AS total_trends,
sum(if(dateTime BETWEEN '"&fromDate&"' AND '"&toDate&"' ,1,0)) as total_last_7_days,
((sum(if(dateTime BETWEEN '"&fromDate&"' AND '"&toDate&"' ,1,0)) /COUNT(*) ) *100)
as percentage // if you want to get only percentage
FROM trending_names
GROUP BY name
ORDER BY COUNT(*) DESC
LIMIT 10;
You can use a subquery :
SELECT name, ((COUNT(*)*100)/(SELECT COUNT(*) FROM trending_names)) AS total_trends
FROM trending_names
WHERE dateTime BETWEEN '"&fromDate&"' AND '"&toDate&"' // -7 days to Now()
GROUP BY name
ORDER BY COUNT(*) DESC
LIMIT 10;
I know you aren't running SQL Server, but some readers might be interested to see this compact solution that's possible (SQL Server 2008 or later). I'm not sure many people know you can have a windowed aggregate that aggregates an aggregate.
select
name,
100.0*count(*)/sum(count(*)) over () as pct_trends
from trending_names
where dateTime between getdate()-7 and getdate()
group by name;
No, I don't think so. You do need to compute that total count on a separate (sub)select
SELECT name,(total_trends*100.0/sum_total_trends) pct_trends
FROM
(
SELECT name, COUNT(*) AS total_trends
FROM trending_names
WHERE dateTime BETWEEN '"&fromDate&"' AND '"&toDate&"' // -7 days to Now()
GROUP BY name
WITH ROLLUP
) A,
(
SELECT COUNT(*) AS sum_total_trends
FROM trending_names
WHERE dateTime BETWEEN '"&fromDate&"' AND '"&toDate&"' // -7 days to Now()
) B;