Blog Post

Cartesian/Cross Join

I was once asked in a job interview if I knew what a Cartesian/Cross Join was.

A more interesting question is: How can a Cross Join be useful?

There are actually many good reasons to use a Cross Join. Outlined below are a couple the most common scenarios that I have used in Data Warehousing:

1. Junk Dimension

In addition to the advantages listed in the Kimball article, Junk Dimensions can greatly reduce the overhead of processing a large dimension. Consider the following real life scenario:

An existing type 1 slowly changing customer dimension with 10 + million members, needs  to have a set of Flag/Boolean attributes (one for each day of the week) added to it. and just make things worse these attributes need to be type 2. Do you change the already large dimension to SCD 2 on attributes that change might frequently? NO!

Solution: Create a Junk Dimension with all possible combinations of the Flags/Boolean indicators. see screen shots:

–create table to hold weekday values
declare @WeekFlag table
(Sunday bit,
Monday bit,
Tuesday bit,
Wednesday bit,
Thrusday bit,
Friday bit,
Saturday bit)
–insert boolean values for the each weekday
insert into @WeekFlag values( 0,0,0,0,0,0,0)
insert into @WeekFlag values( 1,1,1,1,1,1,1)
–look at table
select * from @WeekFlag
– self join table by using cross join
select a.Sunday,b.Monday,c.Tuesday,d.Wednesday,e.Thrusday,f.Friday,g.Saturday
from (select Sunday from @WeekFlag) as  a
cross join (select Monday from @WeekFlag) as  b
cross join (select Tuesday from @WeekFlag) as  c
cross join (select Wednesday from @WeekFlag) as  d
cross join (select Thrusday from @WeekFlag) as  e
cross join (select Friday from @WeekFlag) as  f
cross join (select Saturday from @WeekFlag) as  g


2. Time Dimension

“Time Dimension” here does not mean a Time Dimension with the granularity of a day (like AdventureWorks) but a Dimension with a granularity LESS THAN A DAY. Example: analyze transactions down to the millisecond.

Don’t try to combine a Dimension with a granularity of a day with one of a millisecond you will end up with billions or more members!!


Cross Join each level of the Time Dimension.

Milliseconds –> Seconds –> Minutes –> Hours

here is an example of the first cross join in the series:

declare @MilliSecTable table ( MilliSecValue int)
declare @Msec as int = 0
    insert into @MilliSecTable values (@Msec)
while (select MAX(MilliSecValue) from @MilliSecTable) < 999
    insert into @MilliSecTable values((select MAX(MilliSecValue) from @MilliSecTable) + 1)
declare @SecTable table ( SecValue int)
declare @Sec as int = 0
    insert into @SecTable values (@Sec)
while (select MAX(SecValue) from @SecTable) < 59
    insert into @SecTable values((select MAX(SecValue) from @SecTable) + 1)

select SecValue,MilliSecValue from @SecTable cross join @MilliSecTable


**Note: The above code also performs a lot better than simply each incrementing each member by 1 millisecond. That could literally take days ;)


The Many-to-Many Revolution: This takes the basic idea of T-SQL Cross Joins and applies them to SSAS. It is a great read!


You rated this post out of 5. Change rating




You rated this post out of 5. Change rating