Mysql. Change date format output on GROUP BY DAY query - mysql

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.

Related

Avg function not returning proper value

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.

Format a string to a date in MySQL query

I have a table as shown below, the date column is a string(MMMM-yyyy).
I want to select the latest row for an ID. For ID # 2, the latest date would be August-2020 with the price of 45.40
ID Date Price
2 August-2020 45.40
2 July-2020 42.30
I've tried the format(date, 'MMMM-yyyy) as formatted date and STR_TO_DATE(date, '%MMMM-%yyyy') but I can't get it to convert to a date so I can order the column. I want to keep the date in this format, I just need to order it for my query.
Use str_to_date() to convert the string to a date; a little trick is needed to make the original value a complete date string before conversion, so:
str_to_date(concat(date, '-01'), '%M-%Y-%d')
To filter the table on the latest date per id, you would do:
select t.*
from mytable t
where date = (
select date
from mytable t1
where t1.id = t.id
order by str_to_date(concat(date, '-01'), '%M-%Y-%d') desc
limit 1
)
You need to proper format specifiers for MySQL. I would expect this to work:
select STR_TO_DATE('August-2020', '%M-%Y')
However, it appears that you need:
select str_to_date(concat('01-', 'August-2020'), '%d-%M-%Y')
Here is a db<>fiddle.

Calculate average column value per day

I have the following table structure: Value (stores random integer values), Datetime` (stores purchased orders datetimes).
How would I get the average value from all Value rows across a full day?
I'm assuming the query would be something like the following
SELECT count(*) / 1
FROM mytable
WHERE DateTime = date(now(), -1 DAY)
You can GROUP BY the DATE part of DATETIME and use AVG aggregate function to find an average value for each group :
SELECT AVG(`Value`)
, DATE(`Datetime`)
FROM `mytable`
GROUP BY DATE(`Datetime`)
Looks like a simple AVG task:
SELECT `datetime`,AVG(`Value`) as AvgValue
FROM TableName
GROUP BY `datetime`
To find average of a specific day:
SELECT `datetime`,AVG(`Value`) as AvgValue
FROM TableName
WHERE `datetime`=#MyDate
GROUP BY `datetime`
Or Simply:
SELECT AVG(`Value`) as AvgValue
FROM TableName
WHERE `datetime`=#MyDate
Explanation:
AVG is an aggregate function used to find the average of a column. Read more here.
The following query will give you what u want..
SELECT DATE_FORMAT(thedate_field, '%Y-%m-%d') as theday, avg (value)
FROM mytable group by
DATE_FORMAT(thedate_field, '%Y-%m-%d')
Try It its work...
Select AVG(value),convert(nvarchar,DateTime,103) from table group by convert(nvarchar,DateTime,103)

MySQL Query not selecting correct date range

Im currently trying to run a SQL query to export data between a certain date, but it runs the query fine, just not the date selection and i can't figure out what's wrong.
SELECT
title AS Order_No,
FROM_UNIXTIME(entry_date, '%d-%m-%Y') AS Date,
status AS Status,
field_id_59 AS Transaction_ID,
field_id_32 AS Customer_Name,
field_id_26 AS Sub_Total,
field_id_28 AS VAT,
field_id_31 AS Discount,
field_id_27 AS Shipping_Cost,
(field_id_26+field_id_28+field_id_27-field_id_31) AS Total
FROM
exp_channel_data AS d NATURAL JOIN
exp_channel_titles AS t
WHERE
t.channel_id = 5 AND FROM_UNIXTIME(entry_date, '%d-%m-%Y') BETWEEN '01-05-2012' AND '31-05-2012' AND status = 'Shipped'
ORDER BY
entry_date DESC
As explained in the manual, date literals should be in YYYY-MM-DD format. Also, bearing in mind the point made by #ypercube in his answer, you want:
WHERE t.channel_id = 5
AND entry_date >= UNIX_TIMESTAMP('2012-05-01')
AND entry_date < UNIX_TIMESTAMP('2012-06-01')
AND status = 'Shipped'
Besides the date format there is another issue. To effectively use any index on entry_date, you should not apply functions to that column when you use it conditions in WHERE, GROUP BY or HAVING clauses (you can use the formatting in SELECT list, if you need a different than the default format to be shown). An effective way to write that part of the query would be:
( entry_date >= '2012-05-01'
AND entry_date < '2012-06-01'
)
It works with DATE, DATETIME and TIMESTAMP columns.

MySQL select only 1 per match

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