This question already has answers here:
Average time in hours,minutes and seconds in php
(4 answers)
Closed 8 years ago.
I have this table on my database.
+--------- --------- ------------+
| id | time | date |
+--------- --------- ------------+
| 1 | 0:12 | 03/30/2014 |
--------- --------- ------------
| 2 | 0:14 | 04/09/2014 | <-- date today
--------- --------- ------------
| 3 | 0:32 | 04/09/2014 | <-- date today
--------- --------- ------------
| 4 | 0:24 | 04/09/2014 | <-- date today
--------- --------- ------------
The time is only minutes and seconds. I want to get the total SUM of the time and get the average. The average count is depending on how many new records are added today which is 3.
Record count/s for today (04/09/2014) = 3
New time records for today:
0:14
0:32
0:24
Total Time for today = 1:10
Average = 1:10 / 3
MySQL Solution:
select
avg( str_to_date( time, '%i:%s' ) ) 'avg t in sec',
date(date) date
from entries
group by 2;
Demo # MySQL 5.6.6 Fiddle
Results as observed on my console:
mysql> select
-> sum( str_to_date( time, '%i:%s' ) ) t,
-> date
-> from entries
-> group by 2;
+------+---------------------+
| t | date |
+------+---------------------+
| 12 | 2014-03-30 00:00:00 |
| 70 | 2014-04-09 00:00:00 |
+------+---------------------+
2 rows in set (0.00 sec)
mysql> select
-> avg( str_to_date( time, '%i:%s' ) ) 'avg t in sec',
-> date(date) date
-> from entries
-> group by 2;
+--------------+------------+
| avg t in sec | date |
+--------------+------------+
| 12.0000 | 2014-03-30 |
| 23.3333 | 2014-04-09 |
+--------------+------------+
2 rows in set (0.00 sec)
Related
I've this MySQL table my_table:
+-------+------------+-----------+
|Student| Date | Classroom |
+-------+------------+-----------+
| 1 | 2018-01-01 | 101 |
| 2 | 2018-01-01 | 102 |
| 3 | 2018-01-01 | 103 |
| 1 | 2018-03-01 | 104 |
| 2 | 2018-06-01 | 103 |
| 3 | 2018-09-01 | 104 |
| 1 | 2018-11-01 | 106 |
| 2 | 2018-12-01 | 101 |
+-------+------------+-----------+
The students stay in the assigned classroom till changed.
I'm trying to get which classroom they were in for a certain month.
For example in October(10), student 1 was in 104, 2 was in 103, and 3 was in 104.
I'm really unsure on how to proceed with this one so any help is appreciated.
Currently using this query based on Strawberry answer
SELECT x.*
FROM my_table x
LEFT OUTER JOIN my_table y
ON y.student = x.student
AND y.date < x.date
WHERE x.date <= LAST_DAY('2018-10-01')
GROUP BY student
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(Student INT NOT NULL, Date DATE NOT NULL, Classroom INT NOT NULL,PRIMARY KEY(student,classroom));
INSERT INTO my_table VALUES
(1,'2018-01-01',101),
(2,'2018-01-01',102),
(3,'2018-01-01',103),
(1,'2018-03-01',104),
(2,'2018-06-01',103),
(3,'2018-09-01',104),
(1,'2018-11-01',106),
(2,'2018-12-01',101);
SELECT x.*
FROM my_table x
JOIN
( SELECT student
, MAX(date) date
FROM my_table
WHERE date <= LAST_DAY('2018-10-01')
GROUP
BY student
) y
ON y.student = x.student
AND y.date = x.date;
+---------+------------+-----------+
| Student | Date | Classroom |
+---------+------------+-----------+
| 1 | 2018-03-01 | 104 |
| 2 | 2018-06-01 | 103 |
| 3 | 2018-09-01 | 104 |
+---------+------------+-----------+
Here's a go at it (snippet to go in a stored procedure; assumes table called example & output to table months). It produces a row per student for each month of the range.
drop table months;
create table months (month date, student integer, classroom integer);
set #month = (select min(date) from example);
start_loop: LOOP
insert into months select #month, s1.student, classroom from
(select student, max(date) as maxdate from example where date <= #month group by student) s1
join example s2 on s1.student = s2.student and maxdate = date;
if #month = (select max(date) from example) then
leave start_loop;
end if;
set #month = #month + interval 1 month;
END LOOP start_loop;
Let's break the problem into two parts. Firstly, find all the rooms which have been allocated to student A so far and sort them using the date. Next, find the record which is just before or equal to the required month.
For example:
Consider student 1. We get
+-------+------------+-----------+
|Student| Date | Classroom |
+-------+------------+-----------+
| 1 | 2018-01-01 | 101 |
| 1 | 2018-03-01 | 104 |
| 1 | 2018-11-01 | 106 |
+-------+------------+-----------+
Now, let's say for month June we try to find month just less than or equal to 2018-06-01 to get the required room number. I hope this will help.
Example my_table
ID | Name | Date
--------------------------
12 | John | 123456789
13 | Mike | 987654321
...
29 | Rick | 123498765
30 | Adam | 987651234
show output result like this
Month | Count
--------------------------
3 | 5 |
6 | 8 |
How can I do this with PHP?
You can do this using MySQL Query as below.
SELECT MONTH(FROM_UNIXTIME(`Date`)) `Month`
,COUNT(ID)
FROM my_table
GROUP BY `Month`;
Since post tagged codeigniter
This is codeigniter way:
$query = $this->db->select("month(from_unixtime(`Date`)) as `month`, count(1) as `count`",FALSE)
->group_by("month");
->get("your_table");
I have a table like this:
// Times
+----+-------------+
| id | timestamp | // echo date('d/m/Y', $time)
+----+-------------+
| 1 | 1448460315 | // 25/11/2015 -- today
| 2 | 1428440265 | // 07/04/2015
| 3 | 1418160365 | // 09/12/2014
| 4 | 1448460215 | // 25/11/2015 -- today
| 5 | 1438440265 | // 01/08/2015
| 6 | 1438340265 | // 31/07/2015
| 7 | 1438437265 | // 01/08/2015
| 8 | 1448370315 | // 24/11/2015 -- yesterday
| 9 | 1148370315 | // 23/05/2006
| 10 | 1447870315 | // 18/11/2015 -- last week ({11-18}/11/2015)
+----+-------------+
Note: All those number in timestamp column are made of time() function using PHP.
Now I want to know, how can I select all rows which are today Or all rows which are yesterday, or last week?* (it should be noted, in MySQL NOW() is the same with time()).*
For example:
// Times - Today
+----+-------------+
| id | timestamp | // echo date('d/m/Y', $time)
+----+-------------+
| 1 | 1448460315 | // 25/11/2015 -- today
| 4 | 1448460215 | // 25/11/2015 -- today
+----+-------------+
You would need to use the MySQL BETWEEN function
use PHP to get the timestamp from midnight of day to 11:59:59 of day
date_default_timezone_set('America/Chicago');
$day_begins = strtotime(date('Y-m-d 00:00:00', strtotime('today')));
$day_ends = strtotime(date('Y-m-d 11:59:59', strtotime('today')));
-- sql code will look like
SELECT id FROM table WHERE `timestamp` BETWEEN ($day_begins AND $day_ends)
With something like:
SELECT
id,
timestamp
FROM
table
WHERE
DATE_FORMAT(FROM_UNIXTIME(`timestamp`), '%y-%m-%d') = (DATE_FORMAT(NOW(), '%y-%m-%d') - INTERVAL 1 DAY)
How can I get the month interval of a transaction from the last date of it's record to the current date?
Let's look at the table below!
---------------------------------------
|transaction_dates | transaction_time |
---------------------------------------
|2015-01-02 | 11:00:00 |
|2015-01-03 | 12:00:00 |
|2015-02-05 | 7:00:00 |
|2015-03-05 | 10:00:00 |
|2015-03-05 | 19:00:00 |
|2015-04-05 | 13:00:00 |
---------------------------------------
From the current date, August 20, 2015. I don't have any transaction for the month of May,June and July. So by doing some PHP script and SQL, how can I get the months wherein transaction becomes idle to the current date? In the above case, my desired output would be
-------------
|months_idle|
-------------
|5 |
|6 |
|7 |
--------------
Create table with months (1..12) in your DB and select all month > max(MONTH(transaction_dates)) and < MONTH(NOW())
I am creating a graph where I can get the total views everyday for a certain range, or as long it goes back.
The problem I am having is to fill a default number of 0 when no views has been made for a certain day, some days there may be absolutely no views in a day so I need MySQL to return a default of 0 when none is found - I have no idea how to do this.
This is the query I use to get the total views a day:
SELECT DATE(FROM_UNIXTIME(v.date)) AS date_views,
COUNT(v.view_id) AS total_views
FROM
(
views v
)
GROUP BY date_views
ORDER BY v.date DESC
My results return this:
+------------+-------------+
| date_views | total_views |
+------------+-------------+
| 2012-10-17 | 2 |
| 2012-10-15 | 5 |
| 2012-10-14 | 1 |
| 2012-10-10 | 7 |
+------------+-------------+
However there are missing days that I want to return 0 for it, as 2012-10-16, 2012-10-11, 2012-10-12, 2012-10-13 is not included.
So, for example:
+------------+-------------+
| date_views | total_views |
+------------+-------------+
| 2012-10-17 | 2 |
| 2012-10-16 | 0 |
| 2012-10-15 | 5 |
| 2012-10-14 | 1 |
| 2012-10-13 | 0 |
| 2012-10-12 | 0 |
| 2012-10-11 | 0 |
| 2012-10-10 | 7 |
+------------+-------------+
Would be returned.
How would this be approached?
When I did this a couple of years ago I created an empty array with the date as key and the default value 0. Then I simply looped through the result att changed the value for those dates I had.
for each($result as $row){
$date_stats_array[$row['date']] = $row['value'];
}
In situations like this I create a temporary table which I fill with all the dates you want. After that, you can use that table to join your original query against.
To fill the table you can use this procedure:
DROP PROCEDURE IF EXISTS filldates;
DELIMITER |
CREATE PROCEDURE filldates(dateStart DATE, dateEnd DATE)
BEGIN
WHILE dateStart <= dateEnd DO
INSERT INTO tablename (_date) VALUES (dateStart);
SET dateStart = date_add(dateStart, INTERVAL 1 DAY);
END WHILE;
END;
|
DELIMITER ;
CALL filldates('2011-01-01','2011-12-31');
Courtesy of https://stackoverflow.com/a/10132142/375087