# Complex Percent complete over Time query problem

INTRO

I have a query problem that I have been revisiting time to time over the past few months that just seems simple as can be when i think it in my head, but kicks my butt every time I try to implement it. So I'm seeking your help.

SETUP

I have a few tables in play here.... I'm going to lay them out with general wording, in hopes of keeping it as simple as possible. Please excuse me if I miss an important detail on the first go around.

First have a table tracking the manufacturing of widgets. Each widget has a number of properties tracked (columns), as well as a quantity to be manufactured for this job AND amount of time allotted for the manufacturing of them.

Table 1 Eg.:

``````WidgetName(UID) | Size | Shape | Color | Quantity | EstimatedHrs
Widget1         | 2lbs | Square| Red   | 7        | 21
Widget2         | 5lbs | Circle| Red   | 2        | 18
Widget3         | 5lbs | Circle| Blue  | 5        | 45
ect....
``````

Second I have a table that records how much time has been spent working on each widget type and who worked on them, and When. (for the sake of simplicity, assume that once the number of Hrs working on them = EstimatedHrs, Widget quantity is 100% complete)

Table 2 Eg.:

``````LogEntry(UID)  | UserID  |  WidgetName  |  HrsWorked  |  Date/TimeStamp
101            | 3       |  Widget1     |   3         | 2016-10-20 13:57:57
102            | 3       |  Widget2     |   1.5       | 2016-10-20 13:57:57
103            | 3       |  Widget1     |   5         | 2016-10-21 14:57:57
``````

CURRENT UNDERSTANDINGS

In the above setup, We assume the current "Job" is everything in Table 1. So My method for finding the Current Percent complete for this "Job" is relatively simple.

``````SELECT SUM(COALESCE(t2.HrsWorkd,0) / t1.EstimatedHrs * 100) AS JobPercentComplete
FROM Table1 t1
LEFT JOIN Table2 t2
ON t2.WidgetName = t1.WidgetName
``````

I have been successful with finding the percentComplete of different groupings. Eg. what PercentComplete are we for all "Red" widgets?

``````SELECT SUM(COALESCE(t2.HrsWorkd,0) / t1.EstimatedHrs * 100) AS PercentComplete
FROM Table1 t1
LEFT JOIN Table2 t2
ON t2.WidgetName = t1.WidgetName
GROUP BY t1.Color /*Shape,Size,ect...*/
``````

This ability to get percent complete by different grouping via changing only that GROUP BY statement, lends very nicely to putting in a stored procedure and returning different results based off a passed in string.

FINALLY

I have also been successful getting the JobPercentComplete Over Time via:

``````SET @csum := 0;

SELECT Date(t2.Date/TimeStamp) AS Date,
@csum := @csum + (SUM(COALESCE(t2.HrsWorkd,0) / t1.EstimatedHrs * 100)) AS CumulativePercentComplete

FROM Table1 t1
LEFT JOIN Table2 t2
ON t2.WidgetName = t1.WidgetName
GROUP BY DATE(t2.Date/TimeStamp)
ORDER BY DATE(t2.Date/TimeStamp)
``````

QUESTION:

After all of that, this is the simple question I can NOT make an EASY to manipulate statement to answer. Show me the Percent complete over time grouped by Color.

FAILED EXAMPLE 1

``````SET @csum := 0;

SELECT Date(t2.Date/TimeStamp) AS Date,
@csum := @csum + (SUM(COALESCE(t2.HrsWorkd,0) / t1.EstimatedHrs * 100)) AS CumulativePercentComplete

FROM Table1 t1
LEFT JOIN Table2 t2
ON t2.WidgetName = t1.WidgetName
GROUP BY DATE(t2.Date/TimeStamp), t1.Color
``````

The above fails because the double grouping makes it so t1.EstimatedHrs != the total estimated hours for ALL of the color.. but instead only for the Estimated hours for All of the color AND same Date... So if a widget wasn't worked on that day, the calculation is off.

FAILED EXAMPLE 2

``````SET @csum := 0;
SET @currentColor := 0;

SELECT Date(t2.Date/TimeStamp) AS Date,
@csum := @csum + (SUM(COALESCE(t2.HrsWorkd,0) / (SELECT sum(EstimatedHrs) FROM Table1)* 100)) AS CumulativePercentComplete

FROM Table1 t1
LEFT JOIN Table2 t2
ON t2.WidgetName = t1.WidgetName
GROUP BY DATE(t2.Date/TimeStamp), t1.Color
``````

The above fails because the result from the Nested Select statement is the total of ALL EstimatedHrs, instead of just the Hrs for the individual Color. P.S. I suppose this could also be done as a join statement to run much quicker. But would still be the wrong number.

FAILED EXAMPLE 3

I have messed with some complex solutions all ending in failure for 2 reasons.. one, they didn't work, but most importiantly 2, I could not change the out put grouping of the statement by simply changing a grouping statement or such, so that I can use/maintain the SAME query to give results for multiple groupings.... As apposed to making a different query for every single grouping. Keep in mind this is a simplified data example.. the real world one has 10's of different potential grouping options.

CONCLUSION

This problem has proven to be far easier "said than done". I know I'm missing something obvious, so hopefully a fresh set of eyes can point me in the right direction. Thanks

Desired Result

Per Request this is the type of result I'm looking to get. With a single call to a Stored Procedure, passing in only a single string that will define what to group by.

Back I want to get

``````| Size | Shape | Color   |   HrsWorked   |  Date/TimeStamp      |  PercentComplete
| Rand | Rand  | RED     |       3       | 2016-10-20 13:57:57  |    42.9
| Rand | Rand  | RED     |       5       | 2016-10-21 13:57:57  |    101.1
``````

First, I understand that depending on the grouping selected (Color/Size/Shape/ect..) That only the specified grouping will be a valid column, I'm okay managing that on the receiving end of this data. (Hence my usage of the word Rand for Random.

Second, I want the Percent complete to be Percent of "Red" widgets complete.. not Percent of "Job" complete. Hope this clarifies.

• First, I've prepared a test on Rextester so we can all experiment with your sample data and solutions. Could you please show us what would be your desired result on your sample data? – Insac Nov 8 '16 at 22:10
• @Insac Please see the added segment to the bottom of my post. Thanks for the reply.. – DarbyM Nov 9 '16 at 23:59
• Do you have the ability to use Window Functions? I think they fit well your problem, if your variant of mySQL can use them. – joanolo Dec 31 '16 at 13:10
• @joanolo Thanks for the input, but that is a negative.. I don't see where MySQL supports this functionality you linked to. – DarbyM Jan 4 '17 at 15:50

I think the grouping you are looking after is hrsworked along with color: Try this on test prepared by Insac on Rextester :

``````SET @csum := 0;

SELECT Date(t2.log_ts) AS Date,
@csum := @csum + (SUM(COALESCE(t2.HrsWorkd,0) / t1.EstimatedHrs * 100)) AS CumulativePercentComplete,t1.Color,HrsWorkd

FROM (Table1 t1
Left JOIN Table2 t2
ON t2.WidgetName = t1.WidgetName)
GROUP BY  t1.Color ,t2.HrsWorkd
``````

• This solution does not provide the desired results. Digging into it for a better description of how it fails... but in short, it doesn't match the "Desired Results" as spelled out above. – DarbyM Jan 4 '17 at 16:12
• What are we missing ? By failing you means its throwing error or just that its not giving the format you wanted the output to be in ? – Shivam Kumar Jan 4 '17 at 19:57
• No there is no error of any sort, it just "does not provide the desired results/ effect." – DarbyM Jan 5 '17 at 23:37