I have a MySQL table with 5 rows:
email
message_id
date
time
And I would like to count the number of emails there is per days.
So far I have this
SELECT Date,COUNT(*) AS Num FROM mail2_mailing_log WHERE Id_message=#Id GROUP BY Date ORDER BY Date DESC
But we found out that there was a problem with a script and many data got multiplied (Which have since been fixed), but I would like to be able to use the data I have.
So basically I would want to "merge" all the rows that match per email, date and time and then group by date and count the number of items.
SELECT q.date, COUNT(*)
FROM (SELECT DISTINCT email, date, time
FROM mail2_mailing_log
WHERE Id_Message = #Id) q
GROUP BY q.date
ORDER BY q.date DESC
Use the distinct keyword:
SELECT DISTINCT Date,COUNT(*) AS Num FROM mail2_mailing_log WHERE Id_message=#Id GROUP BY Date ORDER BY Date DESC
If the Date column contains the time too, then you will need to format the Date column using the DATE_FORMAT() function.
SELECT DATE_FORMAT(Date, '%W %M %Y'),COUNT(*) AS Num FROM mail2_mailing_log
WHERE Id_message=#Id GROUP BY DATE_FORMAT(Date, '%W %M %Y')
ORDER BY DATE_FORMAT(Date, '%W %M %Y') DESC
Related
I expect this query to give me the avg value from daily active users up to date and grouped by month (from Oct to December). But the result is 164K aprox when it should be 128K. Why avg is not working? Avg should be SUM of values / number of current month days up to today.
SELECT sq.month_year AS 'month_year', AVG(number)
FROM
(
SELECT CONCAT(MONTHNAME(date), "-", YEAR(DATE)) AS 'month_year', count(distinct id_user) AS number
FROM table1
WHERE date between '2020-10-01' and '2020-12-31 23:59:59'
GROUP BY EXTRACT(year_month FROM date)
) sq
GROUP BY 1
Ok guys thanks for your help. The problem was that on the subquery I was pulling the info by month and not by day. So I should pull the info by day there and group by month in the outer query. This finally worked:
SELECT sq.day_month, AVG(number)
FROM (SELECT date(date) AS day_month,
count(distinct id_user) AS number
FROM table_1
WHERE date >= '2020-10-01' AND
date < '2021-01-01'
GROUP BY 1
) sq
GROUP BY EXTRACT(year_month FROM day_month)
Do not use single quotes for column aliases!
SELECT sq.month_year, AVG(number)
FROM (SELECT CONCAT(MONTHNAME(date), '-', YEAR(DATE)) AS month_year,
count(distinct id_user) AS number
FROM table1
WHERE date >= '2020-10-01' AND
date < '2021-01-01'
GROUP BY month_year
) sq
GROUP BY 1;
Note the fixes to the query:
The GROUP BY uses the same columns as the SELECT. Your query should return an error (although it works in older versions of MySQL).
The date comparisons have been simplified.
No single quotes on column aliases.
Note that the outer query is not needed. I assume it is there just to illustrate the issue you are having.
I execute this query
SELECT * FROM graph WHERE ean IN ('00000000166330') group by DAY(created_at);
Getting those results:
# id, ean, avg_price, created_at
'58', '00000000166330', '2799.0000', '2020-06-11 16:43:27'
I want to change the date format returned of the created_at field.
I would like to get only the date, not the hour, and with the format: Day, month, Year.
My guess is that DATE_FORMAT should be used, but how to use it, grouping also by day?
Example here
You are not doing any aggregation, so remove group by
You can replace the operator IN with = because you are comparing against 1 value only
Use the function DATE() to get only the date part from created_at
You need a correlated subquery in the WHERE clause to get the row with the minimum id (since it does not matter whic row will be returned) of each day:
SELECT g.id, g.ean, g.avg_price, DATE_FORMAT(g.created_at, '%d-%m-%Y') created_at
FROM graph g
WHERE g.ean = '00000000166330'
AND g.id = (SELECT MIN(id) FROM graph WHERE ean = g.ean AND DATE(created_at) = DATE(g.created_at))
See the demo.
If you want distinct values without aggregation function you should use DISTINCT and for date you can use the date_format() function
SELECT DISTINCT DAY(created_at)
, date_format(date(created_at),'%d, %m, %Y') , id, avg_price
FROM graph WHERE ean = '00000000166330';
and when you have only a value you should use = and not IN operator.
I have a table with 4 columns:
1. customerID
2. dateAdded
3. productID
4. quantity
The format of dateAdded is like this: 20180730 (YearMonthDay).
I want to group the rows in the table by year and month.
I tried the code below but it doesn't work. I still see rows with the same year and month repeated, but different day.
SELECT dateAdded
, SUM(quantity)
FROM testTable
GROUP
BY DATE_FORMAT(dateAdded, '%Y%m')
, dateAdded
ORDER
BY dateAdded DESC
Any idea how to fix this?
Thank you
Do not group by what you do not want the data to be grouped. Since you provide dateAdded as a parameter to be grouped with, it splits the data by dateAdded and you gain nothing out of year-month grouping. Remove the columns from select/groupby that you use for grouping like this:
SELECT DATE_FORMAT(dateAdded, '%Y%m')
, SUM(quantity)
FROM testTable
GROUP BY
DATE_FORMAT(dateAdded, '%Y%m')
If you store dateAdded as 20180730, looks like it's a string, so it wont work with DATE_FORMAT function, you can use SUBSTRING instead
something like
SELECT dateAdded, SUM(quantity), SUBSTRING(dateAdded, 1, 6) as d
FROM testTable
GROUP BY d
ORDER BY dateAdded DESC
use year and month function
SELECT Year(dateAdded) as YearOfDate,Month(dateAdded) as MonthOfdate,
, SUM(quantity) as Qty
FROM testTable
GROUP
BY Year(dateAdded), Month(dateAdded)
ORDER BY dateAdded DESC
I have the following query:
SELECT DATE_FORMAT(order_completed, "%c/%Y") AS Month, COUNT(*) AS Total_Transactions, SUM(order_total_grand) as Total_Spend FROM `shop_orders` GROUP BY DATE_FORMAT(order_completed, "%c/%Y") DESC
Which outputs the following table:
How can I sort the table by date correctly?
Don't order by the string version of the date. Order by the original date:
SELECT DATE_FORMAT(order_completed, "%c/%Y") AS Month, COUNT(*) AS Total_Transactions,
SUM(order_total_grand) as Total_Spend
FROM shop_orders
GROUP BY DATE_FORMAT(order_completed, "%c/%Y")
ORDER BY MIN(order_completed) DESC;
Strings are ordered as strings, not dates.
I'm trying to group posts from same day, the problem is that 2/20 gets grouped with 3/20 (20 = 20)
How can this be fixed?
This is my current code:
select day(Date), count(*) from Posts WHERE shopID != '' group by shopID, day(Date)
You need to group by every piece that might be different. So add MONTH(Date) and even YEAR(Date) depending on the scope of your query.
select DAY(Date), count(*) from Posts WHERE shopID != '' group by shopID, YEAR(Date), MONTH(Date), DAY(Date)
You could also group this way: UNIX_TIMESTAMP(date(date)), instead of grouping by year, month and day separately
select date(date), count(*) from Posts
WHERE shopID != ''
group by shopID, UNIX_TIMESTAMP(date(date))
Note you'll have to also take the other date data in the select statement to be able to recognize which month/year the day belongs to. If you don't you'll get a lot of day numbers and counts, but the day numbers will be repeated for each month/year.
That's why I used date(date), count(*).