views:

302

answers:

2

I have a table with weekly data that looks like:

userID       Site             date
------      ------           ------
Smith    Ferris Wheel       2009-07-13
Jones   Outerspaceland      2009-07-13
LChar   Ferris Wheel       2009-07-14
Smith     Underworld        2009-07-16
Jones     Fish Bowl         2009-07-17
Munson    Go-Go Tech        2009-07-16

Currently I have a PHP script that first gets the date range (Monday -- Friday), then does a query for each userID for that date range. Then, I loop through the results and check for gaps between dates. If there is gap, it outputs the date and the Site is listed as "Stay Home." It has to account for several days in a row (like if the user is only stationed on Monday and Friday that week), and it has to an extra step at the end of each week to make sure that if the user is staying home after Wednesday (thus having Thursday and Friday to fill in as gaps). So there are three checks it has to make, one for users not starting on Monday, one for gaps between days, and one for users ending before Friday...plus it has to account for days in a row for any of those situations.

The script basically creates an array of the date range to check against, and it has worked fine for months. HOWEVER

I was wondering, is there a MySQL function to have days off returned for each user? So that I can have it fill in "Stay Home" in the query and not have to run a funky script that takes forever to explain to other people working with me on my script?

Thanks!

A: 

Check out this SO question.

Joel Meador
Wow, thank you for spotting that. Unfortunately, the service account I am set up with for the DB doesn't have temporary table privs. But I'll see if I can't pull teeth to change that. That looks like the perfect solution.
Anthony
If you don't have tempo privileges, you can just make a permanent table -- you might want to anyway if you use these queries a lot -- that contains all the dates for the 60y around today's date or something. Change that number based on your needs.
Joel Meador
That seems so silly, just having a table of dates, but it may come to that. This is why I thought there would be a function already in place, to avoid making utility tables like that. Ah well. So I would do a left join of two queries then? One query for the data, one for the date range, right?
Anthony
Yeah, it kind of sucks, but sql is about querying existing data. If you want it pure sql, there isn't another way to do it.How you end up getting the end result isn't obvious, as I'm not really sure what it will look like. There will definitely be some left join in there. :)
Joel Meador
So the idea is this:First there is a query that gets all the user names. Then there is a foreach loop that queries the weekly schedule for each user. But to make it look consistent (thus avoiding the "Oh, I thought it was on Tuesday but I have Tuesday off!") the missing days are filled in. It also needs to do a nested conditional query to find out if ANY of the users are scheduled for a weekend date, so that the date range extends the extra two days so that even if a user has that weekend off, they can know for sure.
Anthony
A: 

Easy! Flip the query around!

That is:

  1. Create a lookup table with the days of the week
  2. Sculpt a query that performs a LEFT_OUTER_JOIN on the lookup table and your table DAYNAME(field). That is, it will return all rows from the lookup table and only those that match in your table,,,

I'm not sure if you want to filter by person .. the criteria would look like userid = 'person' or userid is null

The resulting data will look be ...

  1. A ROW for ALL DAYS
  2. In the row, UserIDs will exist for Non Blank Days and be null for days skipped
CMB
If I have a table that is just Monday - Sunday that I could reuse over and over, is there a date function that will, based on the actual date range reverse those weekdays into actual dates? One of my goals is to have as much of, if not all of, my html actual returned by the SQL query using concat and whatnot, so while using your idea does the trick for finding missing days, it would be ideal if it returned those missing weekdays as the missing dates (wrapped up in the html tags etc).
Anthony
Yes, it is possible to get both. Does your table include only a weeks worth of data?Include in the query a calculated column that does a date calculation based up on the starting date (which you pass in). There is also the option of UNION on a small table with dates and grouping by to remove any duplicates.
CMB
IF by a week's worth of data you mean doe the table only have data for one specific week, no. If you mean does it only every query for one week's worth of data, usually, but not always, so no again. I think I'll have to go with Joel's suggestion of having a table of dates instead. I would much rather have a lighter table of just 7 values, but it seems that to really get everything I want without the luxury of temp tables, I'll have to just have a 365 * 20 value table with just every day of the year.
Anthony
A table of dates would work. If you didn't want to maintain date data, you could even probably fudge it with a table of partial dates...etc.or Temp tables...Good luck
CMB