Tag Archives: Joins

Tips & Tricks #12: How to Troubleshoot Cross Joins in SQL Reports for the SQL Generation Engine 9.x

MicroStrategy Community Banner


In my last blog post, I blogged about the new MicroStrategy Community. Jaime Perez, VP of Worldwide Customer Services, and his crew have come up with a better way for us to engage with MicroStrategy as well as his team.

Speaking of Jaime, last June, he posted this great tip on the MicroStrategy Knowledgebase site as a TechNote. I am reblogging it since it is one of the most frequent questions I get asked and I find it an extremely useful Tip & Trick. Also, this will give you an idea of the great stuff being posted in the MicroStrategy Community.

Best Regards,


MicroStrategy and Cross Joins

In some scenarios, one may encounter cross joins in the SQL View of a standard, SQL Report in MicroStrategy.  Cross joins appear when two tables do not have any common key attributes between them in which they can inner join.  As a result, the two tables essentially combine together to create one table that has all the data from both tables, but this results in poorer performance with a common effect of increased execution times.  Sometimes these execution times, and performance hits, can be very severe.  Therefore, it is important to understand some simple steps that can be performed to resolve a cross join, as well as some steps to understand why it may be appearing in the SQL View of the report.

One common occurrence of a cross join is when a report contains at least two unrelated attributes in the grid, and no metrics are present in order to relate the unrelated attributes via a fact table.  Such a occurrence can be resolved in a few ways:

  1. Create a relationship filter, set the output level as the unrelated attributes (or the entire report level), and then relate these by a Logical Table object
  2. Create a relationship filter, set the output level as the unrelated attributes (or the entire report level), and then relate these by a Fact object
  3. Add a metric to the report that uses a fact from a table in which both attributes can inner join to

This provides a pathway from the fact table to the lookup tables in which the unrelated attributes are sourced from.  The result is an inner join between the fact table and the lookup tables, which resolves the cross join between the two unrelated lookup tables.

Options 1 and 2 provide a means in which the report template can remain as only attributes, whereas Option 3 would have a metric on the report.  Option 3 may not be desired if a metric does not want to be placed on the report.  Keep in mind that other techniques can also be employed to have the metric on the report, but formatted to be hidden from display.

More common scenarios include cross joins between a fact table and a lookup table, and are typically surprising to a developer.  These situations can be a bit more tricky to troubleshoot and resolve, but here are a few techniques that can be employed to try to resolve the issue:

  1. In SQL View look at where the cross join appears, and between which tables the cross join appears
  2. Open up those tables in the Table Editor by navigating to the Schema Objects\Tables folder, and double-clicking the tables
  3. Select the Logical View Tab of both tables to see all the logical objects mapped to the table
  4. Take note of which attributes have a key icon beside them
  5. These key attributes denote attributes at the lowest level of their hierarchy presently mapped to the table and/or attributes that are in their own hierarchy (meaning they have no parents or children)
  6. The SQL Engine will join 2 tables on common key attributes only, so if none of the key attributes on either table exist on both tables, then a cross join should appear

This means that just because a Region attribute exists on Table_A and a Region attribute exists on Table_B does not necessarily mean that the SQL Engine will join on Region.  If Region has its child attribute on the table, then that attribute should be the key as it is the lowest level attribute of its particular hierarchy mapped to the table.  If Region exists on both tables, and is also a key attribute on both tables, then an inner join should take place on Region.

This essentially means that one can find a cross join, investigate the tables in which it appears, and verify if at least 1 common key attribute exists between the tables.  If not, then that should be the first path to investigate because a cross join is correct in that scenario.


You can find a detailed video on how this issue is reproduced and resolved here: Tech Note 71019 . Steps to reproduce and resolve


MicroStrategy Technical Support can assist with resolving cross joins in a specific report, however caution should be taken when resolving such issues.  In some scenarios, the cross join is resolved through modifications to the schema objects, which can have a ripple effect to all other reports in an environment.  For example, if a relationship is changed in the Region attribute to resolve a cross join in one report, this change will be reflected in all other reports that use Region, and potentially the hierarchy in which Region belongs.  As a result, the SQL View of one report will have the cross join resolved, but the SQL may have changed in other reports using Region or its related attributes.  This may or may not be desired.  MicroStrategy Technical Support may not be able to fully understand the impact of such a schema change to the data model, so before a change is made to the data model the consequences of such a change should be fully understood by the developer, and any changes made to the schema should be recorded.


[1] Jaime Perez, TN47356: How to troubleshoot cross joins in SQL Reports for the SQL Generation Engine 9.x, MicroStrategy Community, 06/24/2014, http://community.microstrategy.com/t5/Architect/TN47356-How-to-troubleshoot-cross-joins-in-SQL-Reports-for-the/ta-p/196989.

[2] MicroStrrategy Knowledgebase, Tech Note 71019 . Steps to reproduce and resolve,

Bryan Redux #1: Left Joins in MicroStrategy


I am occasionally going to re-blog posts from my friend, Bryan Brandow’s MicroStrategy site.

I consider Bryan one of the best in the business, but his passions lie in other areas these days.

I will denote these blogs by beginning them with “Bryan Redux.” If you want to visit Bryan old site, the URL is http://www.bryanbrandow.com.

Best Regards,


Bryan posted this on Tuesday, March 22, 2011.

Left Joins in MicroStrategy

Bryan BrandowAn interesting stance by MicroStrategy is that they really push you for proper warehouse modeling (or at least what they consider proper).  At the same time, the tool’s flexibility can really handle just about any model, and I’ve seen the SQL Engine come through in some amazing scenarios where other vendors laughed and walked out.  One commonly requested feature is the ability to left join two tables in a report.  That is, left join Dimension to Fact, not left joining multiple passes.  There are plenty of valid reasons you would need this feature, and for many years I would joke “MicroStrategy can do everything .. except Left Joins”.  Imagine my surprise when I discovered an extremely buried feature that does enable left joins!  I stumbled on this a several months ago and have no idea if it’s been there all along or was introduced recently.  Based on forum and friend activity, not many other people are aware of it either.  Today, I’ll show you the secret.

Build a normal report with Attribute1, Attribute2 and a Metric.  The SQL will come out like this:

select a12.Attribute1  Attribute1, a13.Attribute2  Attribute2, sum(a11.Fact)  Metric

from FactTable a11 join DimAttribute1 a12

on (a11.Attribute1Key = a12.Attribute1Key)

join DimAttribute2 a13   on (a11.Attribute2Key = a13.Attribute2Key)

group by a12.Attribute1, a13.Attribute2

But let’s say that you need to left join DimAttribute2 to FactTable.  Simply follow these steps:

Step 1: Edit the Attribute

  1. In the attribute editor, go to Tools -> VLDB Properties.
  2. Change the property Joins -> Preserve all final pass result elements to the third option, Preserve all elements of final pass result table with respect to lookup table but not relationship table.
  3. Update Schema.

Step 2: Edit the Report

  1. In the report editor, go to Data -> VLDB Properties.
  2. Change the property Joins -> Preserve all final pass result elements to the fourth option, Do not listen to per report level setting, preserve elements of the final pass according to the setting at the attribute level.

With those two options combined, the resulting report now generates this SQL:

select a12.Attribute1  Attribute1, a13.Attribute2  Attribute2, sum(a11.Fact)  Metric

from FactTable a11 join DimAttribute1 a12

on (a11.Attribute1Key = a12.Attribute1Key) left outer join DimAttribute2 a13 

on (a11.Attribute2Key = a13.Attribute2Key)

group by a12.Attribute1, a13.Attribute2

Conclusion Note that since you need to turn on a report level setting, changing the attribute won’t modify your entire system.  This is nice because you can choose to let some reports to left join on that attribute while not others.  One side effect I have experienced is that this attribute is no longer eligible for Intelligent Cubes. If you can live with that, this becomes a pretty handy trick.

Bryan’s Blog Entry Link:  http://www.bryanbrandow.com/2011/03/left-joins-in-microstrategy.html