I have a list of users and their birthdays. I need to print the list of birthdays for each month and grouped by day. For example:
Monday 24th (2): Herpina Derpina, John Doe
Tuesday 27th (1): Nicolas Cage
Friday 28th (1): Michael Jackson
How could I achieve that with one single SQL call? If I group them this way, I will lose records:
SELECT COUNT(*) FROM user GROUP BY MONTH(birthday)
Any ideas? (I'm using mysql + php)
You can't get the count which is an aggregate function and the detailed records in the same query. If the names are essential then you will have to manually construct the counts in PHP and then display the records under the required format.
SELECT MONTH(birthday) month,
FORMAT(birthday, '%W %D') day,
COUNT(user) count,
GROUP_CONCAT(user SEPARATOR ',') users
FROM table
GROUP BY MONTH(birthday), FORMAT(birthday, '%W %D')
Related
I have a SQL Table of logins as a data source, and each row has an id, timestamp and user_id.
Similar to this:
id
timestamp
user_id
1
2022-01-01T15:17:13.000Z
234
2
2022-01-02T15:17:13.000Z
235
I want to build a report that shows an aggregate of logins by year. So something like (for all months, just using January as an example.):
Year
Active Users in January
Logins in January
2019
500
10000
2020
600
10002
Essentially, the active users would be grouping the rows of logins by user_id, and the logins would just aggregate the timestamps by month.
Is this kind of view something I build using a SQL query?
You may use aggregation here:
SELECT
YEAR(timestamp) AS Year,
COUNT(DISTINCT user_id) AS `Active Users in January`,
COUNT(*) AS `Logins in January`
FROM yourTable
WHERE
MONTH(timestamp) = 1
GROUP BY
YEAR(timestamp);
The number of active users is given by the distinct count of users for a given year, in the month of January. The number of logins is just the number of entries for a given year in January.
If you want to report for all months and all years, then use:
SELECT
DATE_FORMAT(timestamp, '%Y-%m') AS ym,
COUNT(DISTINCT user_id) AS `Active Users per month`,
COUNT(*) AS `Logins in month`
FROM yourTable
GROUP BY 1;
My query return like below
date count
November 19,2019,11:58 PM 2
November 19,2019,11:59 PM 2
November 20,2019,12:02 AM 2
Is there any way to do like
November 19,2019 4
November 20,2019 2
follow this query:
I get this result when I execute the query
select count(*) from listings group by date(created)
Seems your date is not a standard mysql date time format. We need to format it first using str_to_date function.
select cast(str_to_date(dateC, '%M %d,%Y,%h:%i') as date), count(1) from Test
group by cast(str_to_date(dateC, '%M %d,%Y,%h:%i') as date)
see dbfiddle.
I'm working to write a MySQL query that outputs the number of new users created by week.
My user table is:
id | created_at
My query:
SELECT YEAR(created_at) AS Year, DATE_FORMAT(created_at, '%b %e') AS Week, COUNT(*) AS total
FROM users
GROUP BY Year, Week;
The problem:
Years: I would like the most recent year to be at the top, currently the oldest year is at the top of the output.
Weeks: The week column is not sorted based on the calendar. For example, the last records shows: 2019 | May 9 | 100
Where I'd like the year and week sorted.
I think you'll find the function YEARWEEK() helpful, not only for the grouping, but also for the ordering.
Also, your use of DATE_FORMAT() doesn't look right, because you're outputing the %e, which is the day of the month, yet you're grouping by week?
SELECT DATE_FORMAT(created_at, '%Y %b %v') AS date, COUNT(*) AS total
FROM users
GROUP BY YEARWEEK(created_at)
ORDER BY YEARWEEK(created_at) DESC;
I have a database with multiple columns from which I have created this view where I have multiple rows similar to the ones shown below. The data is available for each day of the month from 2009 to 2010 and for all the month for the 5 names given. I have to get the 'Name' for which the occurrence of category 'Super' is more than 5 times each month and list them out separately for each month. The view contains data for all months together.
Name Dates Category
--------------------------------
PAT 2009-01-01 Super
YAT 2009-01-01 No
ROT 2009-01-01 No
SUP 2009-01-01 Super
ANT 2009-01-01 Super
I tried getting a count of the Name in MySQL using
SELECT `NAME`,`DATES`
FROM (
SELECT `NAME`, `CATEGORY`,MONTH(`DATES`)
FROM VIEW
GROUP BY `NAME`, `CATEGORY`,MONTH(`DATES`)
HAVING COUNT(`CATEGORY`)>5
) a
GROUP BY `NAME`
HAVING count(`CATEGORY`)>5;
But it does not return any rows.
You're trying to group your rows into months. The best way to do this is to start with an expression that will take any date and convert it to the first day of the month in which it occurs. That expression is.
DATE(DATE_FORMAT(dates, '%Y-%m-01'))
Next, you use this expression in a query with a GROUP BY clause.
SELECT NAME, CATEGORY,
DATE(DATE_FORMAT(DATES, '%Y-%m-01')) DATES
FROM VIEW
GROUP BY NAME, CATEGORY, DATE(DATE_FORMAT(DATES, '%Y-%m-01'))
HAVING COUNT(*) > 5
This will yield all the name / category / month combinations occurring more than five times.
I think that's what you want. But maybe you want all the monthly items listed in any month where the Super category appears more than five times for some name. To do that first we write a subquery to get a list of those dates:
SELECT DATE(DATE_FORMAT(DATES, '%Y-%m-01')) DATES
FROM VIEW
WHERE CATEGORY = 'Super'
GROUP BY NAME, DATE(DATE_FORMAT(DATES, '%Y-%m-01'))
HAVING COUNT(*) > 5
Then we write a main query to get all the data
SELECT DISTINCT
NAME, CATEGORY,
DATE(DATE_FORMAT(DATES, '%Y-%m-01')) DATES
FROM VIEW
WHERE DATE(DATE_FORMAT(DATES, '%Y-%m-01')) IN
(
SELECT DATE(DATE_FORMAT(DATES, '%Y-%m-01')) DATES
FROM VIEW
WHERE CATEGORY = 'Super'
GROUP BY NAME, DATE(DATE_FORMAT(DATES, '%Y-%m-01'))
HAVING COUNT(*) > 5
)
The trick to getting this sort of thing to work is choosing the right date-arithmetic expression to use in your GROUP BY clause. The functions like DAY(), MONTH(), and YEAR() are surprisingly difficult to use correctly, so I think you may find DATE(DATE_FORMAT(dates, '%Y-%m-01')) more reliable.
I need some help. I want to find a birthday in a selected month, for example is this.
SELECT * FROM students WHERE DOB between '1777-01-01' AND '3000-01-31';
They only get the year. How can I get the value of month I selected?
To get a particular month regardless of year, you may want to do this:
SELECT DATE_FORMAT(DOB, '%e %M') AS birthday
FROM students
WHERE MONTH(DOB) = 1
ORDER BY DAY(DOB)
for January. This will scan your table and pick up all the January DOB values and order them by the day in January of their birthdays.