The way you described is one way, and likely the simplest to get the results you want. The good news there is that you only need to set up that calculated field once in each data source and then Tableau will take care of updating it when you refresh the data.
An alternative to get rid of the overlapping text is to aggregate at a higher level by using table calculations, where there are two components done in the same calculation:
1. Create a table calculation that will return the same result for every row returned, so even though the text would still overlap, it would all be the same number and end up looking bold and slightly fuzzy in the table.
2. Adjust the calculation so it only returns one value for one row in the partition, and NULL for everything else. This gets rid of the overlapping text.
3 (optional). Adjust the calculation once more so that it is only computed once for the whole partition. This improves performance.
So, for a basic SUM([Sales]) calc, the revised calculation that implements all three steps would be something like:
IF FIRST()==0 THEN
Richard Leeke wrote about this method in a great post at http://www.clearlyandsimply.com/clearly_and_simply/2011/01/another-look-at-site-catchment-analysis-with-tableau-6-part-3.html
Table calculations are completely dependent on the Compute Using settings and unless you have a good handle on that they can return unexpected and incorrect results, and two factors that can make them more complicated are blends and working with date hierarchies.
You didn't give specifics on your data source(s), however one additional method is to do the left-join in your data source, either via Custom SQL in Tableau or as a query or stored proc in the database. This can let you get the blend at the right level of detail, not require too much granularity on the Level of Detail Shelf, and still be able to use the regular aggregates.
I've found this latter method to be easier maintain than the table calculation approach. In my work, I have to do a lot of reporting on irregular event data such as the # of infections where a given unit in the hospital can go months or years without an infection. In order to make sure Tableau still shows the details for that unit, in the underlying query (we use MS Access for this data) generates a list of all month/unit combinations and then left-joins the event data (one row per infection event) to that. Then I have a # of Events calculated field that is something like SUM(IF NOT ISNULL([Event ID]) THEN 1 END) that is used in showing infections over time, calculating rates, etc.
I hope this helps, and I'm interested in what other people have to say as well!