MySQL Query Between Multiple Dates in another table
Feel like this should be something easy that I'm missing. I have a table with multiple timestamps throughout a day, and another table with date ranges. I want to select from the first table whenever it's timestamp is in any of the date ranges in the other table, for a specific day... Anyone have any clue how that could work or if it's even possible?
Edit
SELECT count(*) FROM Completed /* Returns 59 */
SELECT count(u.user_id) AS Total FROM Completed c
LEFT JOIN users u ON c.user_id = u.user_id
LEFT JOIN logins l ON c.user_id = l.user_id开发者_运维问答
WHERE c.start BETWEEN l.signIn AND l.signOut
AND c.users_id = 1400
GROUP BY c.type, c.user_id
ORDER BY c.type, Total /* Returns 57 Total */
So, my three tables are:
- User. user_id int, fullname varchar.
- Complete. user_id int, type varchar, start datetime
- Logins. user_id int, signIn datetime, signOut datetime
Essentialy I have multiple rows in the complete table, and I want to know how much that the user did, versus how much they had an opportunity to do. "Having the opportunity" is simply being signed in, so I'm trying to get a breakdown of each users total worked, versus available for any work that came in while they were signed in. The thing is they'll have multiple sign in periods throughout one day. I thought I was close above, but no cigar.
Edit 2
Okay, here's what the tables might look like. In the example below I'd want to see that John had the opportunity to work 4 and worked 2 of them. I wouldn't want to count complete_id 4 because he wasn't at work yet. My ideal result would look something like:
name | type | available | worked | sign in | sign out
Jack | SUV | 1 | 1 | 2011-04-08 12:30:00 | 2011-04-08 13:00:00
Jack | SUV | 3 | 0 | 2011-04-08 13:30:00 | 2011-04-08 14:00:00 // Had An Opportunity to work, but didn't work any
Jack | SUV | 5 | 2 | 2011-04-08 14:30:00 | 2011-04-08 15:00:00 // Worked two
users table
user_id | fullname
1400 | Jack
1401 | John
complete table
complete_id | user_id | type | start
1 | 1400 | Car | 2011-04-08 18:36:22
2 | 1400 | Boat | 2011-04-08 12:31:42
3 | 1401 | SUV | 2011-04-08 11:14:12
4 | 1400 | Car | 2011-04-08 1:56:52
5 | 1401 | Car | 2011-04-08 16:11:23
logins table
login_id | user_id | signIn | signOut
1 | 1400 | 2011-04-08 1:00:00 | 2011-04-08 21:00:00
1 | 1401 | 2011-04-08 11:00:00 | 2011-04-08 21:00:00
select a.*
from tbl a
where exists (
select *
from tblother b
where b.startdate <= a.datecolumn
and b.enddate >= a.datecolumn)
The following SQL should work for you to get the counts you are looking for. The only thing which is missing is the type of work completed. Only having that in the completed tables complicates things a bit, but I am sure it is doable with a bit more thinking.
The basic idea here is we are building a complete dataset of values and aggregating the counts we need. I use this method a lot when working across date ranges. It is usually pretty efficient too.
SELECT Users.Name, Users.SignIn, Users.SignOut,
SUM(CASE WHEN Complete.Start BETWEEN Users.SignIn AND Users.SignOut THEN 1 Else 0) as Available,
SUM(CASE WHEN Complete.Start BETWEEN Users.SignIn AND Users.SignOut AND Users.User_Id = Complete.User_Id THEN 1 ELSE 0) as Worked
FROM Users inner join logins on users.user_id = logins.user_id, Complete
GROUP BY Users.Name, Users.SignIn, Users.SignOut
You may want to add a WHERE statement to restrict the date range (and number of rows) of the query including complete and logins tables.
精彩评论