What do you do when you need to create a field that's a calculated value based on real data?
If you've used the DB2 Web Query for IBM i development tools, you may have noticed the ability to create two types of virtual fields: defined fields and computed fields. Often, when building a report, you need to create a field that is not in the original database but is instead a calculated value based on real data. For example, "gross profit" may not actually exist in your data, but it can be calculated from revenue and cost values. Each virtual field type has its own distinct advantages and purpose in report development. This TechTip uses a real-world example to illustrate when you should use which field type.
First, I'll define at a high level what each field type is used for, and then I'll explain how the field types are executed when you run a report. Further, I'll show an example that will help you visualize the differences between the field types. I'll also show a neat way to have your computed fields recalculated at the subtotal level to ensure correct subtotal results.
Defined Fields and Computed Fields Compared
A defined field is a virtual field that is executed at an individual row-value level. This means that it is calculated for every row selected in the query. If your query returns 10 rows, 10 distinct values of that virtual defined field are generated. This happens even if your report does not report at the lowest detail level, meaning the values will be executed and then aggregated.
To create a defined field, you use the "New Define Field" icon in Report Assistant, which is circled in Figure 1.
Figure 1: Use the "New Define Field" icon to create a defined field.
You then use the "New Define Field" window to define your virtual field. Each defined field requires a name, formula, and format. In Figure 2, a defined field is created to calculate total cost.
Figure 2: Here's your "New Define Field" window.
A computed field is executed after all sorting and aggregating has been performed during report execution. This means that all of the report's measures (numeric field values) are aggregated (based on the specified sort by columns), and only after this aggregation has occurred are the define field values calculated.
Note: When the report is at the individual-row level, computed fields will have the same value as a defined field. Aggregation is what makes the difference.
To create a computed field, you use the "New Computed Field" icon in Report Assistant, which is circled in Figure 3.
Figure 3: Use the "New Computed Field" icon to create a computed field.
You then use the "New Computed Field" prompt to define your virtual field. As was the case with defined fields, each computed field requires a name, formula, and format (see Figure 4).
Figure 4: This is the "New Computed Field" prompt.
More information on how to use functions, fields, and formats with defined and computed fields can be found in the IBM Redbook Getting Started with DB2 Web Query for System i.
For this example, I will use a table, called Sales, that has five columns (fields) in its metadata: Customer (A10), Item (A10), Quantity (I8), UnitCost (P12.2), and UnitPrice (P12.2). Figure 5 shows the Sales table.
Figure 5: These are the Sales table contents used in the example.
The report I wish to build will show Price, Cost, and Margin values by Customer and Item. It will also subtotal Price, Cost, and Margin for each Customer. Each of the three measure fields--Price, Cost, and Margin--are virtual fields. First, I'll create the report using only defined fields. Then I'll create the report using only computed fields. And finally, I'll use a mixture of the two field types to create a report that returns the correct results.
Report 1: Defined Fields
Using the "New Define Field" icon, I'll create the three defined fields for my report: Price, Cost, and Margin (Figure 6). It is important to note that I need to create Price and Cost before creating Margin, since Margin uses them in its formula.
Figure 6: Here's the "New Define Field" prompt for Cost, Price, and Margin.
I then add the fields to the report, as shown in Figure 7.
Figure 7: I've defined Report 1.
In the Customer field options' Sorting tab, I select "Subtotal numeric sum/print fields" as shown in Figure 8. Then, I set every measure (Cost, Price, and Margin) to be included in the subtotal.
Figure 8: I sort the properties for Report 1.
Next, I'll run the report as both a detail report (Figure 9) and a summary report (Figure 10). This will help explain what's going on in the background of the summary report.
Figure 9: These are the detail-level results for Report 1.
Figure 10: These are the summary-level results.
Notice that the Margin value in the summary report is the sum of the calculated detail or row-level Margin. This is not what I wanted. The same thing also happened with the subtotal values. What I really wanted was for my Margin value calculation to be the sum of the Price and Cost values at the Item level. Will computed fields help me with this?
Report 2: Computed Fields
Using the "New Computed Field" icon, I create the three computed fields for my report: Price, Cost, and Margin (Figure 11). Again, I need to create Price and Cost before creating Margin, since Margin uses them in its formula.
Figure 11: Here's the "New Computed Field" prompt for Price, Cost, and Margin.
By default, the "New Computed Field" prompt will add the created fields to the report. All I need to do is add the Sort By fields, as shown by Figure 12.
Figure 12: I've defined Report 2.
As in Report 1, in the Customer field options' Sorting tab, I select "Subtotal numeric sum/print fields." I also set every measure (Cost, Price, and Margin) to be included in the subtotal.
Next, I run the report as a summary report (Figure 13).
Figure 13: These are the summary-level results for Report 2.
Notice that the Margin values in the summary report are now correct. However, the subtotal value for Margin is still the aggregate of the computed values. To fix this problem, I need to select the "Recalculate computed fields using subtotal values" option in the Customer field options' Sorting tab (Figure 14).
Figure 14: Now, I choose the "recalculate" option.
After running this report, I see some new problems have occurred (Figure 15). Each field in this report is now recalculating at the subtotal level, since I set each computed field to recalculate in Figure 14. But at least the subtotal for Margin is now using the aggregate values from the subtotal and recalculating itself.
Figure 15: Report 2 now recalculates all fields.
Report 3: Combining Defined and Computed Fields Puts All the Pieces Together
It is now apparent that, in order to generate the correct results, I need to use a combination of defined fields and computed fields. Because Cost and Price are calculations that can be made at the row level and simply aggregated at any "Sort by" or "Subtotal" level, it makes sense to use the "New Define Field" prompt to create them. For Margin, however, I need its value to always use the aggregated values to in order to calculate correctly at both the "Sort by" and "Subtotal" level. It would then make sense to create Margin as a computed field. Figure 16 shows the definition of Report 3. Note that the Subtotal options are also shown.
Figure 16: Report 3 is defined!
As shown in Figure 17, running Report now returns the correct results I need from my report. Notice that the define fields Cost and Price act like normal fields in a row of the table and that the Margin uses the sums to calculate itself!
Figure 17: Finally! I get correct results by using a combination of defined and computed fields.
Defined, Computed, or Both?
This TechTip has explained the different purposes the two virtual field options for DB2 Web Query for IBM i. Defined fields and computed fields act in very different ways; however, using them in combination will help solve any reporting issue. Computed fields compute at the aggregate level and can recalculate at the subtotal level, while defined fields create a virtual field at the row level of your table.