There are basically two options with your scenario, as I understand it.
- Dynamic SQL (see a_vlad's answer)
- A (potentially) insanely massive
- Return "canned" data.
For option two, you have to know the names of your tables when you write the query - and, those tables have to exist.
So, step one would be determine any future tables that will be needed, and pre-create them. If you can't do this, you can still build the query - but it will have to be modified whenever a new table is added.
So, assuming that your criteria allow us to create as many tables as you'll need for the foreseeable future in advance, next you have to build the new query:
SELECT DATE(COALESCE(t1.timestamp,t2.timestamp, t3.timestamp, t4.timestamp)) As Date
,AVG(COALESCE(t1.Value,t2.Value,t3.Value,t4.Value)) AS Value
LEFT JOIN cmsdb.grouptable gt ON ut.groupID = gt.ID
LEFT JOIN Table1 t1 ON (gt.tablename = 'Table1')
LEFT JOIN Table2 t2 ON (gt.tablename = 'Table2')
LEFT JOIN Table3 t3 ON (gt.tablename = 'Table3')
LEFT JOIN Table4 t4 ON (gt.tablename = 'Table4')
WHERE u.User = 2
AND COALESCE(t1.timestamp,t2.timestamp, t3.timestamp, t4.timestamp) BETWEEN CURDATE()-INTERVAL 4 WEEK AND CURDATE()
GROUP BY DATE(COALESCE(t1.timestamp,t2.timestamp, t3.timestamp, t4.timestamp))
As you can see, this is already pretty unwieldy with 4 tables - with 200, it'd be hideous.
NOTE: code is untested, and I don't mainly work w/ MySQL, but this is simple enough that it should work; you might need to play with exactly where the
COALESCE function should be.
The key here, if it isn't obvious, is that we only actually pay attention to data from the table with the right name.
There are a couple of assumptions here:
- Only one table can be valid for any given user. If a user can belong to multiple groups and thus see multiple tables, the results may not be correct.
- This assumes that you really want a summary of all the table's contents in the date range for any user in the correct group; if there's anything user-specific, you'd need to add that check, using
COALESCE again to pick up the column form the table we actually joined with.
In many ways, a dynamic SQL solution would be easier on the programmer. With that, you can avoid some of the possible problems with this (it can't handle new tables, renamed tables, etc.)
The third option only works if the data returned does not have to be live.
For this option, you create another table - let's call it
GroupSummary. This table has three key values:
grouptable (can be used as key),
GroupSummary would be populated by a dynamic SQL statement, like in a_vlad's answer. You could loop through the possible tables with a cursor, and have the whole thing set up as a stored program. Run the stored program as often as needed to pick up new data (noting that running it too frequently is likely to cause performance issues with your
SELECT query). If reasonably fresh data is required, I'd be thinking refreshing the data every 5-15 minutes; at a minimum, it should be refreshed after midnight (as this would, of course, change the base date it's working from).
Then, the query in your webpage would be:
SELECT SummaryDate as Date
,AvgValue as Value
FROM GroupSummary gs
INNER JOIN grouptable gt ON (gs.grouptable = gt.grouptable)
INNER JOIN usertable ut ON (gt.ID = ut.groupID)
WHERE User = %USERID%
WHERE clause based on your sample query, adjust as needed).