Time-constraint query - mysql

I have the following table:
id | roomid | courseid | day(NUM) | start(TIME) | end(TIME)
This is one part of larget query that I am stuck with. How can I show all id's that have NO time break in between courses in specific rooms on specific day? Kind of stuck here.
I guess I have to use 'ADDTIME()' function to to find out the difference in course1 end time and course 2start time => that have 0. I have been looking at it for quite some time now and I am stuck!

If all you are interested in is full utilisation.
If a day is say 7 hours, (9-5 - 1 hour lunch break), call it 420 minutes to make things easy.
Then 420 - Sum(MINUTE(TIMEDIFF(t2,t1)) = 0 would mean the room was fully booked up.

Perhaps toying with a CTE can help you there. Try starting with something like this
WITH RU_CTE AS (
SELECT your_fields
FROM RoomUtilization
WHERE day = #DayParameter
AND start = #startTimeParameter
UNION ALL
SELECT your_fields
FROM RoomUtilization RU
WHERE day = RU_CTE.day
AND start = RU_CTE.end
)
SELECT *
FROM RU_CTE
and see if some twiches satisfy your needs
But as eggyal said, it's probably easier to get the data for the day and room and solve this on the application code.

Related

candle creation on a monthly basis using the scores in mysql

I am trying to create a candle using the table as below. It has a score and month and there can be as many as 4 scores in a month.
id | score | month
1 | 10 | 12
.. | .. | ..
And here is what I actually did,
select
score as open,
max(score) as high,
min(score) as low
from score_table
group by month
I am successful in getting Open, high and low.
My problem is getting the close, basically the fourth score of a month. I tried some solutions using joins unfortunately I am wrong and couldn't get it right which actually landed me in too many confusion. I'm not good at SQL and need help...
I see when you group by month the records just give you a high and a low with the same values
What I changed is to get the month and the high and low .
There should be separate columns for the high ,low and open in a list form to break the high lows up per time period (if you only working on one candle its fine but many candles over a time period there should be a row for each time period)
that data is quite hard to work with the way the table is set out but you can construct something like this to make it easier for your self
id | Month | Open | High | Low |
would be more ideal to work with that data but non the the least I changed the the MySQL query a bit to reflect data as per your description. I achieved it by combining 2 MySQL queries to get the open data from row 3
select x.open, y.high, y.low from ( select (score) as open
from score
where id = 3 )as x,
(select max(score) as high,
min(score) as low
from score ) as y;

Need help getting an elapsed time with a lapse query to work

I need help getting a query to work and I'm having trouble conceptualizing it. Generally I want to get the time it takes for a computer to upgrade to a new OS, minus any periods of time in between that are caused by failures.
Example of the table would be:
timestamp - status
2016-07-19 14:25:59.000 Conversion In Progress
2016-07-20 07:38:20.000 Failed - 04
2016-07-26 07:15:59.000 Conversion In Progress
2016-07-26 08:50:39.000 Conversion Successful
You can see there is a big gap from when the conversion initially failed and when it was kicked off again. I want to avoid adding this period of time for reporting purposes.
My query I use right now is this:
SELECT ROUND( AVG((b.ts - a.ts) / 60), 0)
FROM
(
SELECT mach_name, timestamp, UNIX_TIMESTAMP(timestamp)as ts FROM w10_migration_log where status = 'Conversion In Progress'
)a INNER JOIN
(
SELECT mach_name, timestamp, UNIX_TIMESTAMP(timestamp)as ts FROM w10_migration_log where status = 'Conversion Successful'
) b on a.mach_name = b.mach_name
Most entries in the log won't have issues to deal with. Would that matter?
Any help is greatly appreciated
It's not surprising you cannot conceptualize the query, because your table structure is not adapted for this type of query. So you need to start by building the correct table structure.
A correct structure for what you are trying to achieve would be:
| attempt_number | device | started_at | finished_at | status (success or failure) |
With that your query would be extremely straightforward: you could just make a sum of the time difference between finished_at and started_at for each attempt of each (or a given) computer.
Now that we have figured that out, the best way it so to build a temporary table or a view similar to that structure (or better yet, refactor your table), then simply query from it.
A query more or less like this one will build the view we want:
SELECT start.mach_name, start.timestamp as started_at, stop.timestamp as finished_at
FROM w10_migration_log start
join w10_migration_log stop ON stop.timestamp > start.timestamp and stop.mach_name = start.mach_name
where start.status = 'Conversion In Progress'
group by start.timestamp;
Then very simply select from this:
select SEC_TO_TIME(SUM(UNIX_TIMESTAMP(finished_at) - UNIX_TIMESTAMP(started_at)))
FROM (
/* directly the previous query, or a view made from the previous query */
);
I did a quick test and got 18:47:01 with your data sample.

Very complex Group By / Unique / Limit by SQL-command

I actually don't even know how to call this :P, but...
I have one table, let's call it "uploads"
id owner date
-----------------------------
0 foo 20100101120000
1 bar 20100101120300
2 foo 20100101120400
3 bar 20100101120600
.. .. ..
6 foo 20100101120800
Now, when I'ld do something like:
SELECT id FROM uploads ORDER BY date DESC
This would result in:
id owner date
-----------------------------
6 foo 20100101120800
.. .. ..
3 bar 20100101120600
2 foo 20100101120400
1 bar 20100101120300
0 foo 20100101120000
Question: Nice, but, I want to go even further. Because now, when you would build a timeline (and I did :P), you are 'spammed' by messages saying foo and bar uploaded something. I'ld like to group them and return the first result with a time-limit of '500' at the date-field.
What kind of SQL-command do I need that would result in:
id owner date
-----------------------------
6 foo 20100101120800
3 bar 20100101120600
0 foo 20100101120000
Then, after that, I can perform a call for each record to get the associative records in a timeframe of 5 minutes (this is an exmaple for id=6):
SELECT id FROM uploads WHERE date>=20100101120800-500 ORDER BY date DESC
Does anyone now how I should do the first step? (so limiting/grouping the results)
(btw. I know that when I want to use this, I should convert every date (YmdHis=60) to Unix-time (=100), but I don't need the 5 minutes to be exactly 5 minutes, they may be a minute less sometimes...)
I'm not quite clear on the result you are trying to get, even with your examples. Perhaps something with rounding and group by.
SELECT max(id) max_id,owner, (ROUND(date/500)*500) date_interval, max(date) date
FROM uploads GROUP BY date_interval,owner
You may want to use FLOOR or CEILING instead of ROUND, depending on what you want.
Standard SQL doesn't deal with intervals very well.
You are going to need to do a self-join of the table to compare dates of different tuples.
That way, you can easily find all pairs of tuples of which the dates are no more than 500 apart.
However, you really want to cluster the dates in sets no more than 500 apart - and that can't be expressed in SQL at all, as far as I know.
What you can do is something quite similar: split the total time interval into fixed 500-unit ranges, and then cluster all tuples in the table based on the interval they're in. For that, you first need a table or query result with the start times of the intervals; this can be created using a SQL query on your table and a function that either "rounds off" a timestamp to the starting time in its interval, or computes its interval sequence number. Then as a second step you can join the table with that result to group its timestamps according to their corresponding start time. I can't give the SQL because it's DBMS-dependent, and I certainly can't tell you if this is the best way of accomplishing what you want in your situation.
Use an inline view? e.g. something like
SELECT u1.*
FROM uploads u1,
(SELECT date
FROM uploads u2
WHERE u2.owner='foo') datum_points
WHERE u1.date BETWEEN datum_points.date
AND DATE_ADD(datum_points.date INTERVAL 5 MINUTES)
should return all the posts made within 5 minutes of 'foo' making a post.

MySql - Problems in a query construct

I need your help....I'm working on a little Time Management Sytem for my compagny.
I have several tables, including this two tables :
Pointage
Id_check | id_user | week | time | …….
Users
Id_user | first_name | last_name | ………
I would like find a means to construct a report which give me all people who didn't check 5 days for last weeks. For example
Id_user | week | time
So I have created a query like that :
SELECT week,id_user,SUM(time) AS totalW FROM pointage WHERE week<42
GROUP BY id_user,week HAVING totalW<5 ORDER BY id_user
My problem is that this query give me lates only if the person has checked at least one time (for a week).
For example, if the id_user '1' don't check any time for the week 40, he won't appear in my report. An important problem for a query which should give me all people in late in their checks. He will be appeared if he had checked at least one time, for example 1 day.
I have tried to modify my query, I have created a new table 'week', join it with LEFT / RIGHT JOIN but I don't find any solution to solve my wish !
So my last chance is to post this message !
Do you have an idea to obtain this report ?
Thanks very much for your help and sorry for my bad english !
Nicolas
select week.week, users_id_users,
(
select
if(sum(time) is null, 0, sum(time))
from pointage
where users.id_user=pointage.id_user and pointage.week=week.week
group by pointage.id_user
having count(*)<5
) as sum_time
from users, week
where week.week<42
assuming your week table contains record from week 1..52

Grouping timestamps in MySQL with PHP

I want to log certain activities in MySql with a timecode using time(). Now I'm accumulating thousands of records, I want to output the data by sets of hours/days/months etc.
What would be the suggested method for grouping time codes in MySQL?
Example data:
1248651289
1248651299
1248651386
1248651588
1248651647
1248651700
1248651707
1248651737
1248651808
1248652269
Example code:
$sql = "SELECT COUNT(timecode) FROM timecodeTable";
//GROUP BY round(timecode/3600, 1) //group by hour??
Edit:
There's two groupings that can be made so I should make that clearer: The 24 hours in the day can be grouped but I'm more interested in grouping over time so returning 365 results for each year the tracking is in place, so total's for each day passed, then being able to select a range of dates and see more details on hours/minutes accessed over those times selected.
This is why I've titled it as using PHP, as I'd expect this might be easier with a PHP loop to generate the hours/days etc?
Peter
SELECT COUNT(*), HOUR(timecode)
FROM timecodeTable
GROUP BY HOUR(timecode);
Your result set, given the above data, would look as such:
+----------+----------------+
| COUNT(*) | HOUR(timecode) |
+----------+----------------+
| 10 | 18 |
+----------+----------------+
Many more related functions can be found here.
Edit
After doing some tests of my own based on the output of your comment I determined that your database is in a state of epic fail. :) You're using INT's as TIMESTAMPs. This is never a good idea. There's no justifiable reason to use an INT in place of TIMESTAMP/DATETIME.
That said, you'd have to modify my above example as follows:
SELECT COUNT(*), HOUR(FROM_UNIXTIME(timecode))
FROM timecodeTable
GROUP BY HOUR(FROM_UNIXTIME(timecode));
Edit 2
You can use additional GROUP BY clauses to achieve this:
SELECT
COUNT(*),
YEAR(timecode),
DAYOFYEAR(timecode),
HOUR(timecode)
FROM timecodeTable
GROUP BY YEAR(timecode), DAYOFYEAR(timecode), HOUR(timecode);
Note, I omitted the FROM_UNIXTIME() for brevity.