SQL: Get all hits for unique days (timestamps) - mysql

So I have a database table which contains id, action, timestamp for example. I want to get the unique days with corresponding hits/views.
Something like this:
Date ------ Hits
2018-01-10 5
2018-01-11 542
2018-01-12 74
My approach was this:
SELECT DISTINCT FROM_UNIXTIME (timecreated, '%d.%m.%y') AS 'date'
FROM `mdl_logstore_standard_log`
WHERE action = 'viewed'
That lists me all unique days but if I'll add count(action) AS 'hits' to the SELECT statement it will just show me the first day with the sum of all hits.
How can I solve this query? I'm grateful for any hints

You need to group results using GROUP BY
SELECT FROM_UNIXTIME (timecreated, '%d.%m.%y') AS `date`, COUNT(action) AS hits
FROM `mdl_logstore_standard_log`
WHERE action = 'viewed'
GROUP BY FROM_UNIXTIME (timecreated, '%d.%m.%y')
ORDER BY `date`

For your requested output, you should really do:
SELECT FROM_UNIXTIME(timecreated, '%Y-%m-%d') AS `date`, COUNT(*) AS hits
FROM `mdl_logstore_standard_log`
WHERE action = 'viewed'
GROUP BY FROM_UNIXTIME (timecreated, '%Y-%m-%d')
ORDER BY MIN(timecreated);
The order by uses MIN(timecreated) so it will work even if you change the format.

Related

How to select rows with the latest time for each date within the last 30 days from now

Imagine a table with field 'datetime'. Example rows:
2017-01-27 13:06:02
2017-01-27 05:13:14
2017-01-23 22:13:56
2017-01-26 14:02:09
2017-01-23 13:26:12
...
I need to get * from the bold lines, BUT WITHIN the last 30 days from now...
In other words, rows with the max date in the last 30 days.
30 rows in total in each case, assuming every day has at least one row...
You can group by the date part of datetime and get the max for each day.
select max(`datetime`)
from tablename
where `datetime` >= date(now())-interval '30' day
group by date(`datetime`)
To get all the fields from the table for such rows, use
select * from tablename where `datetime` in (
select max(`datetime`)
from tablename
where `datetime` >= date(now())-interval '30' day
group by date(`datetime`)
)
vkp's answer is basically correct, although there's no need for subquery to select the final result from - you can just put other columns straight into your query, up to something like this:
select *, max(datetime)
from tablename
where datetime >= date(now())-interval '30' day
group by date(datetime);
Ah, and that works for joins too.
The other thing I'd change to address the goal more precise, is:
max(time(datetime))
select * from your_table
where datetime between sysdate and sysdate-30

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.

How to group by date regardless of time?

I'm trying to group by Date(). I've got 3 records with the created_at column:
2011-12-03 08:00:24, 2011-12-03 08:12:10, 2011-12-04 09:00:00
I'd like to only group by year, month and day, regardless of time. So for the example above. It should only return two rows:
2011-12-03 and 2011-12-04
How should I go about this?
... group by date(date_time_column)
This should allow you to group by year month and day
SELECT group_by_column
, DATE_FORMAT(created_at, '%Y')
, DATE_FORMAT(created_at, '%m')
, DATE_FORMAT(created_at, '%d')
FROM my_table
GROUP BY group_by_column
or if you want to do them all together.
SELECT group_by_column
, DATE_FORMAT(created_at, '%Y%m%d')
FROM my_table
GROUP BY group_by_column
Did you try the following?
SELECT
DATE(created_at) AS created_date
FROM
my_table
GROUP BY
created_date
MySQL permits GROUP BY DATE(created_at). So that would translate in ActiveRecord to .group(DATE(created_at))
In fact, that exact example is available in the Rails Guides on ActiveRecord querying.
You can use the Date() function.
http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_date
mysql> SELECT DATE('2003-12-31 01:02:03');
-> '2003-12-31'
TRY
GROUP BY DATE(`date_column`)
Reference

MySQL: Getting "busiest" or "most popular" hour from a datetime field?

Consider the following table which has the fields - id (int) and date_created (datetime):
id date_created
1 2010-02-25 12:25:32
2 2010-02-26 13:40:37
3 2010-03-01 12:02:22
4 2010-03-01 12:10:23
5 2010-03-02 10:10:09
6 2010-03-03 12:45:03
I want to know the busiest/most popular hour of the day for this set of data. In this example, the result I'm looking for would be 12.
Ideas?
To get just the most popular hour, use this query
select date_format( date_created, '%H' ) as `hour`
from [Table]
group by date_format( date_created, '%H' )
order by count(*) desc
limit 1;
If you want to look at all the data, go with this one
select count(*) as num_records
, date_created
, date_format( date_created, '%H' ) as `hour`
from [Table]
group by `hour`
order by num_records desc;
If you want something a little more flexible, perhaps to the half hour, or quarter hour, you can do the following:
SELECT floor(time_to_sec(date_created)/3600),count(*) AS period
FROM table GROUP BY period ORDER BY c DESC
If you want the most popular 2 hour interval, use 7200. The most popular 15 minute interval, use 900. You just need to remember you are dealing with seconds (3600 seconds in an hour).
Use the hour() function to extract the hour, then do the usual aggregation:
SELECT count(hour(date_created)) AS c, hour(date_created) AS h FROM table GROUP BY h ORDER BY c DESC;
I like both Simon and Peter's answers, but I can't select both as accepted. I combined the 2 to make a cleaner query that only returned the popular hour (I don't need the counts).
SELECT hour(date_created) AS h
FROM my_table
GROUP BY h
ORDER BY count(*) DESC
LIMIT 1
You could try this:
SELECT
DATE_FORMAT(date,'%H') as hours,
count(*) as count
FROM
myTable
GROUP BY
hours
ORDER BY
count DESC