Mysql Timeclock status and hours updates - php

I have a table to record people clocking in and out. I need to find the best way to get a given person's records and add up their hours in a given time period
Here is the table:
tc_timeclock:
tc_id | user_id | status | time_stamp
-------------------------------------
1 | 1 | IN | 2012-11-28 09:00:25
2 | 2 | IN | 2012-11-28 09:01:25
3 | 3 | IN | 2012-11-26 09:03:25
4 | 4 | IN | 2012-11-28 09:21:25
5 | 5 | IN | 2012-11-28 09:01:12
6 | 6 | IN | 2012-11-28 09:47:13
7 | 7 | IN | 2012-11-12 09:00:22
8 | 7 | OUT | 2012-11-12 09:03:28
9 | 5 | OUT | 2012-11-28 09:21:25
10 | 6 | OUT | 2012-11-28 11:47:13
11 | 3 | OUT | 2012-11-26 11:03:25
12 | 2 | OUT | 2012-11-28 11:01:25
13 | 1 | OUT | 2012-11-28 11:27:25
14 | 4 | OUT | 2012-11-28 11:21:25
15 | 4 | IN | 2012-11-28 12:21:25
16 | 1 | IN | 2012-11-28 12:27:25
17 | 3 | IN | 2012-11-26 12:03:25
18 | 6 | IN | 2012-11-28 12:47:13
19 | 2 | IN | 2012-11-28 12:01:25
20 | 1 | OUT | 2012-11-28 17:27:25
21 | 4 | OUT | 2012-11-28 17:21:25
22 | 3 | OUT | 2012-11-26 17:03:25
23 | 2 | OUT | 2012-11-28 17:01:25
I of course can grab all of the rows for a user and it would include all of the IN and OUT status's.
I just don't know the best way to find the time difference (IE how long were they clocked in) between those statuses
The other issue which may be easy enough, is how to find all of this within a certain date range. (ie today, this business week, this pay period.)
Now I am thinking that a portion of this will need to be done in some php, just can't for the life of me figure out the logic.

Related

How to filter users' data sets by narrowing it from the same data sets in SQL? - 61 joins limit problem

I'm implementing sport testing system where people enter their exercises results.
I'm trying to list the results of exercises filtered with values of other exercises' results.
I use a Codeigniter framework to building SQLs.
Here are the db tables:
"tests"
| id | users_id | test_date |
------------------------------
| 1 | 1 | 2020-03-10 |
| 2 | 1 | 2020-03-12 |
| 3 | 2 | 2020-03-09 |
| 4 | 2 | 2020-03-13 |
"exercises"
| id | name |
------------------
| 1 | exercise1 |
| 2 | exercise2 |
| 3 | exercise3 |
| 4 | exercise4 |
| 5 | exercise5 |
| 6 | exercise6 |
"results"
| id | tests_id | exercieses_id | result |
------------------------------------------
| 1 | 1 | 1 | 35 |
| 2 | 1 | 2 | 12 |
| 3 | 1 | 3 | 23 |
| 4 | 1 | 4 | 34 |
| 5 | 1 | 5 | 45 |
| 6 | 1 | 6 | 56 |
| 7 | 2 | 1 | 67 |
| 8 | 2 | 2 | 12 |
| 9 | 2 | 3 | 54 |
| 10 | 2 | 4 | 89 |
| 11 | 2 | 5 | 35 |
| 12 | 2 | 6 | 31 |
| 13 | 3 | 1 | 35 |
| 14 | 3 | 2 | 12 |
| 15 | 3 | 3 | 23 |
| 16 | 3 | 4 | 34 |
| 17 | 3 | 5 | 45 |
| 18 | 3 | 6 | 56 |
| 19 | 4 | 1 | 67 |
| 20 | 4 | 2 | 12 |
| 21 | 4 | 3 | 54 |
| 22 | 4 | 4 | 89 |
| 23 | 4 | 5 | 35 |
| 24 | 4 | 6 | 31 |
The base query is:
$this->db->select('exercises.id, exercises.name, results.result, tests.test_date');
$this->db->from('results');
$this->db->join('tests', 'tests.id = results.tests_id');
$this->db->join('exercises', 'exercises.id = results.exercises_id');
$this->db->order_by('exercises.id');
and it works well.
Now I'm adding a filtering of all results with the selected narrowing ranges of results defined by min and max values. They are packed in array:
$exercises_results_to_filter = array('exercise1' => array('id' => 1, 'min' => 20, 'max' => 30),
'exercise2' => array('id' => 2, 'min' => 24, 'max' => 28),
... and so on);
Because I have a lot of exercises so I make this loop:
foreach ($exercises_results_to_filter as $name => $exercise)
{
$this->db->join('results AS results_'.$name, 'results_'.$name.'.tests_id = results.tests_id', 'INNER');
$this->db->where('results_'.$name.'.exercises_id = '.$exercise['id']);
$this->db->where('results_'.$name.'.result BETWEEN '.$exercise['min'].' AND '.$exercise['max']);
}
and above query also works well, but only for small amount of JOINs. When 200 exercises go into the work mySQL shouts at me that "Too many tables; MySQL can only use 61 tables in a join"
Please help. What to do??

Create tournament fixture lists

I need help to figure out how to solve this:
We are trying to create a fixture list for a tournament, below you will find a table generated by a webinterface we have. (Not sure if this is the ideal layout to make the fixture list, but I may do changes to what we store and use as a basis for the task below).
The tournament concept is with x number of courts in the same location. So we would like to have court utilization as close to 100% as possible.
The problem is to generate the fixture list itself based on this table without conflicts( a team plays 2 games in same round) and also to have the best utilization of the courts.
Explanation of the concept:
Tournament_id is the id of the main tournament.
Then we have sub tournaments, and they are identified by pool_id. Then each pool may have several groups which play round robin (single/double) group_id.
We have already done the setup of games so the teams playing each other are located in home and visit, and the round within the group is indicated by round. This means if a group has 2 games in round 1 this is the maximum games that can be played in this group for this round, if only one game the maximum is 1.
priority is used as this:
Equal priority means the games should be handled together during creation of fixture list. In the example pool_id=23 has 3 groups, 0,1,2. 1 and 2 has priority 1, and 0 has priority 2.
This means the games for group 0 cannot be played before the games in priority 1 for groups 1 and 2 has been played. (it is used to keep control inside each pool.)
The number of courts in the tournament is known at this stage and for this example it's 4.
I would like to be able to generate the fixture list in 2 different ways:
1: We use the courts column and assign to correct court.
2: We do not use the courts column, and assign games to next available court.
I would like to have an array which I can loop through to make the fixture list, game by game, round by round with indication of the court it is assigned.
mysql> select * from tournament_games where tournament_id=7 order by priority,round,fetch_order;
+---------------+---------+----------+-------+------+-------+--------+----------+-------------+-----------------------+
| tournament_id | pool_id | group_id | round | home | visit | courts | priority | fetch_order | gametype |
+---------------+---------+----------+-------+------+-------+--------+----------+-------------+-----------------------+
| 7 | 20 | 1 | 1 | 156 | 49 | 4 | 1 | 1 | |
| 7 | 20 | 2 | 1 | 80 | 71 | 3 | 1 | 2 | |
| 7 | 18 | 1 | 1 | 69 | 64 | 3-4 | 1 | 4 | |
| 7 | 18 | 1 | 1 | 68 | 65 | 3-4 | 1 | 4 | |
| 7 | 23 | 1 | 1 | 155 | 50 | 1 | 1 | 5 | |
| 7 | 23 | 2 | 1 | 153 | 100 | 2 | 1 | 6 | |
| 7 | 20 | 1 | 2 | 49 | 79 | 4 | 1 | 1 | |
| 7 | 20 | 2 | 2 | 71 | 74 | 3 | 1 | 2 | |
| 7 | 18 | 1 | 2 | 64 | 68 | 3-4 | 1 | 4 | |
| 7 | 18 | 1 | 2 | 69 | 65 | 3-4 | 1 | 4 | |
| 7 | 23 | 1 | 2 | 50 | 99 | 1 | 1 | 5 | |
| 7 | 23 | 2 | 2 | 100 | 151 | 2 | 1 | 6 | |
| 7 | 20 | 1 | 3 | 156 | 79 | 4 | 1 | 1 | |
| 7 | 20 | 2 | 3 | 74 | 80 | 3 | 1 | 2 | |
| 7 | 18 | 1 | 3 | 65 | 64 | 3-4 | 1 | 4 | |
| 7 | 18 | 1 | 3 | 69 | 68 | 3-4 | 1 | 4 | |
| 7 | 23 | 1 | 3 | 155 | 99 | 1 | 1 | 5 | |
| 7 | 23 | 2 | 3 | 153 | 151 | 2 | 1 | 6 | |
| 7 | 20 | 1 | 4 | 49 | 156 | 4 | 1 | 1 | |
| 7 | 18 | 1 | 4 | 65 | 68 | 3-4 | 1 | 4 | |
| 7 | 18 | 1 | 4 | 64 | 69 | 3-4 | 1 | 4 | |
| 7 | 23 | 1 | 4 | 50 | 155 | 1 | 1 | 5 | |
| 7 | 23 | 2 | 4 | 100 | 153 | 2 | 1 | 6 | |
| 7 | 20 | 1 | 5 | 79 | 49 | 4 | 1 | 1 | |
| 7 | 18 | 1 | 5 | 65 | 69 | 3-4 | 1 | 4 | |
| 7 | 18 | 1 | 5 | 68 | 64 | 3-4 | 1 | 4 | |
| 7 | 23 | 1 | 5 | 50 | 99 | 1 | 1 | 5 | |
| 7 | 23 | 2 | 5 | 100 | 151 | 2 | 1 | 6 | |
| 7 | 20 | 1 | 6 | 79 | 156 | 4 | 1 | 1 | |
| 7 | 18 | 1 | 6 | 69 | 68 | 3-4 | 1 | 4 | |
| 7 | 18 | 1 | 6 | 65 | 64 | 3-4 | 1 | 4 | |
| 7 | 23 | 1 | 6 | 99 | 155 | 1 | 1 | 5 | |
| 7 | 23 | 2 | 6 | 151 | 153 | 2 | 1 | 6 | |
| 7 | 20 | 0 | 1 | 0 | 0 | 3-4 | 2 | 3 | partidos de posición |
| 7 | 20 | 0 | 1 | 0 | 0 | 3-4 | 2 | 3 | partidos de posición |
| 7 | 20 | 0 | 1 | 0 | 0 | 3-4 | 2 | 3 | partidos de posición |
| 7 | 20 | 0 | 1 | 0 | 0 | 3-4 | 2 | 3 | partidos de posición |
| 7 | 23 | 0 | 1 | 0 | 0 | 1-2 | 2 | 7 | semifinales |
| 7 | 23 | 0 | 1 | 0 | 0 | 1-2 | 2 | 7 | semifinales |
| 7 | 23 | 0 | 2 | 0 | 0 | 1-2 | 2 | 7 | final y perdedor |
| 7 | 23 | 0 | 2 | 0 | 0 | 1-2 | 2 | 7 | final y perdedor |
+---------------+---------+----------+-------+------+-------+--------+----------+-------------+-----------------------+
41 rows in set (0.00 sec)
Anyone with any suggestions on how to go about solving this?
regards, Roar

time slot for students and teacher

I am looking to set start time for first 20 students of a particular subject
at 9:00 AM and end time 10:00 AM, for the next 20 i want the time for the same subject 10:00 AM- 11 AM , this should happen for each subject, also i want that only 1 teacher for that particular subject should be alloted for each time slot,
i have tried a lot but still unable to come up with the solution.
user_table
user_id | user_name | contact_no | password | flag
6 | Abhis | 123456788 | 123 | s
5 | Abhish | 123456789 | 123 | s
8 | Sneha | 1111111111 | 123 | s
7 | Snehil | 1111112222 | 123 | s
1 | Narsingh | 1234567890 | 123 | t
2 | Abhinav | 1234567891 | 1234 | t
3 | Abhi | 1234567892 | 123 | s
4 | Abhishek | 1234567893 | 123 | s
subject_table
sub_id | sub_name
3 | CSS
1 | HTML
2 | JQUERY
enr_id | sub_id | user_id | date |
1 | 1 | 1 | 2016-04-01 |
2 | 2 | 1 | 2016-04-01 |
3 | 3 | 1 | 2016-04-01 |
4 | 1 | 5 | 2016-04-01 |
5 | 1 | 6 | 2016-04-01 |
6 | 1 | 7 | 2016-04-01 |
7 | 1 | 2 | 2016-04-01 |
8 | 2 | 2 | 2016-04-01 |

MySQL - how to fetch the top combinations of data using same table with multiple combinations of records?

I have table called response_drilldown with the following structure.
These are the my table fields and entries:
| answer_id | responder_id | question_id | answer | level_id |
|-----------|--------------|-------------|---------------|----------|
| 1 | 1 | 25 | India | 1 |
| 2 | 1 | 25 | Andhrapradesh | 2 |
| 3 | 1 | 25 | Guntur | 3 |
| 4 | 2 | 25 | India | 1 |
| 5 | 2 | 25 | Andhrapradesh | 2 |
| 6 | 2 | 25 | Guntur | 3 |
| 7 | 3 | 25 | India | 1 |
| 8 | 3 | 25 | Telangana | 2 |
| 9 | 3 | 25 | Hyderabad | 3 |
| 10 | 4 | 25 | India | 1 |
| 11 | 4 | 25 | Telangana | 2 |
| 12 | 4 | 25 | Warangal | 3 |
| 13 | 5 | 25 | India | 1 |
| 14 | 5 | 25 | Telangana | 2 |
| 15 | 5 | 25 | Nalgonda | 3 |
| 16 | 6 | 25 | India | 1 |
| 17 | 6 | 25 | Telangana | 2 |
| 18 | 6 | 25 | Hyderabad | 3 |
So using the above example, How to get the combination of data using mysql query like :
India > Andhrapradesh > guntur > 2,
India > Telangana > Hyderabad > 2,
India > Telangana > Warangal > 1,
India > Telangana > Nalgonda > 1,
Can anyone please give me the answer?

Mysql Grab last update by user id within a specified timeframe

I have two tables tc_users and tc_timeclock. I want to grab the current status of each active user. But only those that have made an update (clocked in or out) within the last 12 hours. I have gotten as far as figuring out how to grab all of the updates within the last 12 hours but not how to narrow it down to just the last one for each user.
Here are my tables:
tc_users:
user_id | first_name | last_name | active
-----------------------------------------
1 | Frank | Zappa | 1
2 | John | Mcneely | 1
3 | Bill | Mckenna | 1
4 | Mark | langdon | 1
5 | Steve | Mcalister | 0
6 | William | Stevens | 1
7 | John | Jones | 0
tc_timeclock:
tc_id | user_id | status | time_stamp
-------------------------------------
1 | 1 | IN | 2012-11-28 09:00:25
2 | 2 | IN | 2012-11-28 09:01:25
3 | 3 | IN | 2012-11-26 09:03:25
4 | 4 | IN | 2012-11-28 09:21:25
5 | 5 | IN | 2012-11-28 09:01:12
6 | 6 | IN | 2012-11-28 09:47:13
7 | 7 | IN | 2012-11-12 09:00:22
8 | 7 | OUT | 2012-11-12 09:03:28
9 | 5 | OUT | 2012-11-28 09:21:25
10 | 6 | OUT | 2012-11-28 11:47:13
11 | 3 | OUT | 2012-11-26 11:03:25
12 | 2 | OUT | 2012-11-28 11:01:25
13 | 1 | OUT | 2012-11-28 11:27:25
14 | 4 | OUT | 2012-11-28 11:21:25
15 | 4 | IN | 2012-11-28 12:21:25
16 | 1 | IN | 2012-11-28 12:27:25
17 | 3 | IN | 2012-11-26 12:03:25
18 | 6 | IN | 2012-11-28 12:47:13
19 | 2 | IN | 2012-11-28 12:01:25
20 | 1 | OUT | 2012-11-28 17:27:25
21 | 4 | OUT | 2012-11-28 17:21:25
22 | 3 | OUT | 2012-11-26 17:03:25
23 | 2 | OUT | 2012-11-28 17:01:25
So far This is the query I have come up with :
if now = 2012-11-28 18:00:00
SELECT first_name, last_name, status, time_stamp
FROM tc_timeclock
INNER JOIN tc_users
ON tc_timeclock.user_id = tc_users.user_id
WHERE tc_users.active = 1
AND tc_timeclock.time_stamp BETWEEN '2012-11-28 06:00:00' AND '2012-11-28 18:00:00'
This displays everything within the last 12 hours like so:
first_name | last_name | status | time_stamp
-----------------------------------------------------
Frank | Zappa | IN | 2012-11-28 09:00:25
John | Mcneely | IN | 2012-11-28 09:01:25
Mark | langdon | IN | 2012-11-28 09:21:25
William | Stevens | IN | 2012-11-28 09:47:13
William | Stevens | OUT | 2012-11-28 11:47:13
John | Mcneely | OUT | 2012-11-28 11:01:25
Frank | Zappa | OUT | 2012-11-28 11:27:25
Mark | langdon | OUT | 2012-11-28 11:21:25
Mark | langdon | IN | 2012-11-28 12:21:25
Frank | Zappa | IN | 2012-11-28 12:27:25
William | Stevens | IN | 2012-11-28 12:47:13
John | Mcneely | IN | 2012-11-28 12:01:25
Frank | Zappa | OUT | 2012-11-28 17:27:25
Mark | langdon | OUT | 2012-11-28 17:21:25
John | Mcneely | OUT | 2012-11-28 17:01:25
The logic I am looking for:
Grab the first and last name, current status and time the status was logged for each active user within the last 12 hours.
So output should be:
first_name | last_name | status | time_stamp
Frank | Zappa | OUT | 2012-11-28 17:27:25
John | Mcneely | OUT | 2012-11-28 17:01:25
Mark | langdon | OUT | 2012-11-28 17:21:25
William | Stevens | IN | 2012-11-28 12:47:13
User 5 (Steve Mcalister) and 7 (John Jones) are not active so they are not displayed.
User 3 (Bill Mckenna)has no activity within the last 12 hours so he is also no diplayed.
Am I missing something really simple? (I am sure I am)
I have a work around if there is not a simple solution, I could always add two columns to the tc_users table: (tc_users.current_status, and tc_users.status_time) and simply make those the same as the last entry into the tc_timeclock table.
That way I could easily select them, I don't like the idea of making the data redundant though if I don't have to.
Something like this might work for you.
SQL:
SELECT `tc_users`.`first_name`, `tc_users`.`last_name`, `tc_timeclock`.`status`, `temp_table`.`last_updated`
FROM `tc_users`
INNER JOIN `tc_timeclock`
ON `tc_users`.`user_id`=`tc_timeclock`.`user_id`
INNER JOIN (
SELECT `user_id`, MAX(`time_stamp`) AS `last_updated` FROM `tc_timeclock` GROUP BY `user_id`
) AS `temp_table`
ON `tc_users`.`user_id`=`temp_table`.`user_id`
AND `tc_timeclock`.`time_stamp`=`temp_table`.`last_updated`
WHERE `tc_users`.`active`!=0
AND `temp_table`.`last_updated`>(NOW() - INTERVAL 12 HOUR);
OUT:
+------------+-----------+--------+---------------------+
| first_name | last_name | status | last_updated |
+------------+-----------+--------+---------------------+
| William | Stevens | IN | 2012-11-28 12:47:13 |
| Frank | Zappa | OUT | 2012-11-28 17:27:25 |
| Mark | langdon | OUT | 2012-11-28 17:21:25 |
| John | Mcneely | OUT | 2012-11-28 17:01:25 |
+------------+-----------+--------+---------------------+
HTH
Query:
SQLFIDDLEExample
SELECT first_name, last_name, tml.status, tml.time_stamp
FROM (SELECT *
FROM tc_timeclock tl
WHERE tl.time_stamp = (SELECT MAX(time_stamp)
FROM tc_timeclock
WHERE tl.user_id = user_id )) tml
INNER JOIN tc_users
ON tml.user_id = tc_users.user_id
WHERE tc_users.active = 1
AND tml.time_stamp BETWEEN '2012-11-28 06:00:00' AND '2012-11-28 18:00:00'
Result:
| FIRST_NAME | LAST_NAME | STATUS | TIME_STAMP |
---------------------------------------------------------------------
| Frank | Zappa | OUT | November, 28 2012 17:27:25+0000 |
| John | Mcneely | OUT | November, 28 2012 17:01:25+0000 |
| Mark | langdon | OUT | November, 28 2012 17:21:25+0000 |
| William | Stevens | IN | November, 28 2012 12:47:13+0000 |

Categories