CROSS JOIN

While this join type is listed first in the JOINs submenu, in my experience, it’s the least used type. A CROSS JOIN of two tables or table-like database objects results in a Cartesian product. A what? Let’s first understand the result of a Cartesian product and then dive into a real-world problem where a CROSS JOIN shines. Consider the simple example below where there exists two tables: shirt and pant. The shirt table contains four rows of data, one for each possible color. Likewise, the pant table contains four rows of data, one for each possible color.

shirt_idshirt_color
1Red
2Blue
3Black
4Gray
pant_idpant_color
1Blue
2Black
3White
4Tan

The Cartesian product of these two tables would result in the following output:

shirt_idshirt_colorpant_idpant_color
1Red1Blue
1Red2Black
1Red3White
1Red4Tan
2Blue1Blue
2Blue2Black
2Blue3White
2Blue4Tan
3Black1Blue
3Black2Black
3Black3White
3Black4Tan
4Gray1Blue
4Gray2Black
4Gray3White
4Gray4Tan

You may quickly notice that for each shirt color, there is one row for each possible pant color and vice versa. That’s because the Cartesian product of these two tables combines each row from the shirt table with each row from the pant table, resulting in sixteen rows. Use caution when performing CROSS JOINs as they can potentially yield very large and sometimes unintended result sets.

Real-world Problem
CROSS JOINs are particularly useful in instances where gaps exist in your data and it’s desirable to fill them. These gaps tend to exist in temporal data, such as customer purchase dates, rainfall patterns, and hiring practices. Really, anything where data is captured over time. Let’s set the stage for understanding our first real-world problem and solution. The data used throughout this example and captured in the two tables below can be found at livesql.oracle.com.

Orders
The orders table contains one row per order submitted by a customer.

order_idorder_dateorder_modecustomer_idorder_statusorder_totalsales_rep_idpromotion_id
245816-AUG-07 03.34.12.234359 PMdirect101078279.6153
239719-NOV-07 02.41.54.696211 PMdirect102142283.2154
245402-OCT-07 05.49.34.678340 PMdirect10316653.4154
235414-JUL-08 06.18.23.234567 PMdirect104046257155
235808-JAN-08 05.03.12.654278 PMdirect10527826155
238114-MAY-08 08.59.08.843679 PMdirect106323034.6156
244031-AUG-07 09.53.06.008765 PMdirect107370576.9156
235708-JAN-06 08.19.44.123456 PMdirect108559872.4158
239410-FEB-08 09.22.35.564789 PMdirect109521863158
243502-SEP-07 11.22.53.134567 PMdirect144662303159
245520-SEP-07 11.34.11.456789 AMdirect145714087.5160
237916-MAY-07 02.22.24.234567 AMdirect146817848.2161
239602-FEB-06 01.34.56.345678 AMdirect147834930161
240629-JUN-07 04.41.20.098765 AMdirect14882854.2161
243413-SEP-07 05.49.30.647893 AMdirect1498268651.8161
243602-SEP-07 06.18.04.378034 AMdirect11686394.8161
244627-JUL-07 07.03.08.302945 AMdirect1178103679.3161
244727-JUL-08 08.59.10.223344 AMdirect101833893.6161
243214-SEP-07 09.53.40.223345 AMdirect1021010523163
243313-SEP-07 10.19.00.654279 AMdirect1031078163
235526-JAN-06 09.22.51.962632 AMonline104894513.5
235626-JAN-08 09.22.41.934562 AMonline105529473.8
235908-JAN-06 09.34.13.112233 PMonline10695543.1
236014-NOV-07 12.22.31.223344 PMonline1074990.4
236113-NOV-07 01.34.21.986210 PMonline1088120131.3
236213-NOV-07 02.41.10.619477 PMonline109492829.4
236323-OCT-07 05.49.56.346122 PMonline144010082.3
236428-AUG-07 06.18.45.942399 PMonline14549500
236528-AUG-07 07.03.34.003399 PMonline146927455.3
236628-AUG-07 08.59.23.144778 PMonline147537319.4
236727-JUN-08 09.53.32.335522 PMonline14810144054.8
236826-JUN-08 10.19.43.190089 PMonline1491060065
236926-JUN-07 11.22.54.009932 PMonline116011097.4
237027-JUN-08 12.22.11.647398 AMonline1174126
237116-MAY-07 01.34.56.113356 AMonline118679405.6
237227-FEB-07 12.22.33.356789 AMonline119916447.2
237327-FEB-08 01.34.51.220065 AMonline1204416
237427-FEB-08 02.41.45.109654 AMonline12104797
237526-FEB-07 03.49.50.459233 AMonline1222103834.4
237607-JUN-07 06.18.08.883310 AMonline123611006.2
237707-JUN-07 07.03.01.001100 AMonline141538017.8
237824-MAY-07 08.59.10.010101 AMonline142525691.3
238016-MAY-07 09.53.02.909090 AMonline143327132.6
238214-MAY-08 10.19.03.828321 AMonline144871173
238312-MAY-08 11.22.30.545103 AMonline145836374.7
238412-MAY-08 12.22.34.525972 PMonline146329249.1
238508-DEC-07 11.34.11.331392 AMonline1474295892
238606-DEC-07 12.22.34.225609 PMonline1481021116.9
238711-MAR-07 03.34.56.536966 PMonline149552758.9
238804-JUN-07 04.41.12.554435 PMonline1504282694.3
238904-JUN-08 05.49.43.546954 PMonline151417620
239018-NOV-07 04.18.50.546851 PMonline15297616.8
239127-FEB-06 05.03.03.828330 PMdirect153248070.6156
239221-JUL-07 08.59.57.571057 PMdirect154926632161
239310-FEB-08 07.53.19.528202 PMdirect155423431.9161
239502-FEB-06 08.19.11.227550 PMdirect156368501163
239819-NOV-07 09.22.53.224175 PMdirect15797110.3163
239919-NOV-07 10.22.38.340990 PMdirect158025270.3161
240010-JUL-07 01.34.29.559387 AMdirect159269286.4161
240110-JUL-07 02.22.53.554822 AMdirect1603969.2163
240202-JUL-07 03.34.44.665170 AMdirect1618600154
240301-JUL-07 04.49.13.615512 PMdirect1620220154
240401-JUL-07 04.49.13.664085 PMdirect1636510158
240501-JUL-07 04.49.13.678123 PMdirect16451233159
240729-JUN-07 07.03.21.526005 AMdirect16592519155
240829-JUN-07 08.59.31.333617 AMdirect1661309158
240929-JUN-07 09.53.41.984501 AMdirect167248154
241024-MAY-08 10.19.51.985501 AMdirect168645175156
241124-MAY-07 11.22.10.548639 AMdirect169815760.5156
241229-MAR-06 10.22.09.509801 AMdirect170966816158
241329-MAR-08 01.34.04.525934 PMdirect101548552161
241429-MAR-07 02.22.40.536996 PMdirect102810794.6153
241529-MAR-06 01.34.50.545196 PMdirect1036310161
241629-MAR-07 04.41.20.945676 PMdirect1046384160
241720-MAR-07 05.49.10.974352 PMdirect10551926.6163
241820-MAR-04 04.18.21.862632 PMdirect10645546.6163
241920-MAR-07 07.03.32.764632 PMdirect107331574160
242013-MAR-07 08.59.43.666320 PMdirect108229750160
242112-MAR-07 09.53.54.562432 PMdirect109172836
242216-DEC-07 08.19.55.462332 PMdirect144211188.5153
242321-NOV-07 10.22.33.362632 AMdirect145310367.7160
242421-NOV-07 10.22.33.263332 AMdirect146413824153
242516-NOV-06 11.34.22.162552 PMdirect14751500.8163
242617-NOV-06 12.22.11.262552 AMdirect14867200
242710-NOV-07 01.34.22.362124 AMdirect14979055163
242810-NOV-07 02.41.34.463567 AMdirect116814685.8
242910-NOV-07 03.49.25.526321 AMdirect117950125154
243002-OCT-07 06.18.36.663332 AMdirect101829669.9159
243114-SEP-06 07.03.04.763452 AMdirect10215610.6163
243701-SEP-06 08.59.15.826132 AMdirect103413550163
243801-SEP-07 09.53.26.934626 AMdirect10405451154
243931-AUG-07 10.19.37.811132 AMdirect105122150.1159
244101-AUG-08 11.22.48.734526 AMdirect10652075.2160
244227-JUL-06 12.22.59.662632 PMdirect107952471.9154
244327-JUL-06 01.34.16.562632 PMdirect10803646154
244427-JUL-07 02.22.27.462632 PMdirect109177727.2155
244527-JUL-06 03.34.38.362632 PMdirect14485537.8158
244818-JUN-07 04.41.49.262632 PMdirect14551388158
244913-JUN-07 05.49.07.162632 PMdirect146686155
245011-APR-07 06.18.10.362632 PMdirect14731636159
245117-DEC-07 05.03.52.562632 PMdirect148710474.6154
245206-OCT-07 08.59.43.462632 PMdirect149512589159
245304-OCT-07 09.53.34.362632 PMdirect1160129153
245607-NOV-06 07.53.25.989889 PMdirect11703878.4163
245731-OCT-07 11.22.16.162632 PMdirect118521586.2159

Order Items
This table contains one row per order, per item in an order.

order_idline_item_idproduct_idunit_pricequantity
2354131064861
23542311496.843
2354331237947
2354431294147
2354531392148
2354631431653
2354731501758
2354831633061
2354931653764
23541031675168
2354113170145.270
2354123176113.372
23541331826177
23551228946200
23552230857185
23553231186.9188
23554232219188
23555232317190
2355623261.1192
2355723301.1197
23558233925199
235592359226.6204
235612264199.138
235622274148.534
2356322939840
2356422997244
2356523085847
2356623119551
2356723162255
2356823231855
2357122113.3140
23572224546226
235732252788.726
235742257371.829
2357522629529
2357622687532
235772276236.538
2357822894841
235811781226.69
2358217821254
235831797316.812
2358418035513
2358518085514
235912337270.61
2359223592491
2359323709117
235942373617
2359523779617
2359623805.517
2359723819717
2360120582329
2360220937.742
23611228946180
23612229976180
23613230853182
23614231186.9185
23615231622187
2361623261.1194
2361723343.3198
236182359248208
23619236576209
23621228948200
23622229976160
23623231193164
23624231622168
2362523261.1173
2362623343.3177
23627233925179
236282359248189
236312264199.19
2363222721297
2363322997425
2363423085726
23635231186.929
2363623192431
2363723231834
2363823261.137
2363923343.342
236411910146
236421948470.820
2365122894892
2365222939928
236532302133.129
2365423085629
2365523119529
2365623162234
2365723192438
2365823221943
2365923261.144
23651023359745
23651123392550
23651223407254
236612359226.68
23662237367
236632382804.110
236642394116.611
23665239512012
23666240041816
236672406195.820
236682409194.722
236692415339.924
23661024196924
2367122894899
23672230214732
2367323085439
2367423222245
2367523261.148
2367623301.152
23677233591.354
2367823502341.954
23681310648150
2368231104260
2368331173862
2368431238170
23685312749670
2368631294272
2368731431675
2368831554575
236913150183
236923155431
236933163325
2369431653410
236953170145.224
236963176113.324
2369731872.224
2369831932.228
23699320412334
237011910149
2371122741576
237122293968
2371322997315
2371423162121
2371523231724
2371623343.326
2371723392529
2371823502341.932
237213106486
237223108742
237233110427
2372431238110
23725312749613
2372631341717
2372731431521
2372831633030
2372931675432
2372103170145.236
237311820498
237321825241
23741242215010
237422423786
2374324497815
2374424677921
23751310642140
2375231127184
2375331173885
237543127488.486
2375531334588
2375631341790
2375731431593
2375831501793
2375931554598
23751031633099
237511316536103
2375123171132107
2375133176120109
2376122706014
237622276236.54
2376322939913
2376422997317
237652302133.121
2376623119525
2376723162127
2376823192532
2376923261.133
23761023343.336
23771228942130
237722302147119
23773231195121
23774231925131
2377523261.1132
2377623301.1136
237812403113.320
237822412952
237832414438.97
2378424172711
2378524237911
237862424217.815
2378724574.425
237882459624.825
2379131064292
2379231149814
237933127488.423
2379431392134
2379531401935
2380131064226
2380231087518
2380331173823
238043127488.424
2380531334628
2380631402030
2380731431531
2380831501733
2380931554533
23801031633236
23801131675237
2380123176113.340
23801331872.240
23811311738110
2381231247744
2381331334444
2381431392045
2381531431548
2381631633555
238173176113.362
2381831834763
23821310642160
2382231104364
23823311410065
2382431173566
2382531237971
23826312749671
2382731294276
2382831392179
2382931431582
23821031632989
23821131653792
238312409194.737
2383224185645
23833242214646
23834243017450
238352439115.554
2383624574.462
2383724627563
2384122894395
2384222997148
2384323162158
2384423222259
2384523301.161
23846235924977
23851228943200
238522302133.187
23853231186.996
2385423192597
23855233591.3106
2385623502341.9109
2386123301.17
2386223343.35
2386323407114
2386423657727
2386523709028
2386623757332
238672378271.733
238682394116.636
2387122113.352
238722243332.220
23873224546222
238742252788.727
238752253354.232
2387622687542
23881228943150
2388222939490
2388323085696
2388423301.1105
2388523502341.9112
23891310643180
2389231127318
2389331238021
2389431294622
2389531431530
2389631554633
2389731653443
2389831675247
239011910144
239021912142
239031948470.816
2391117871015
239121791262.93
2391317973487
239141799961.410
2391518085515
2391618205218
2391718221433.323
2392131064363
2392231127357
2392331173858
2392431247763
2392531334566
2392631392168
2392731501872
2392831554977
2392931654081
2393130511210
2393230602952
23933306410175
2393430693858
239353077260.78
2393630827810
23937308621113
239383087108.914
23939309127819
23931030993.319
239311310869.330
2394131174190
2394231237736
2394331248239
2394431294641
2394531334645
2394631341845
2394731401948
2394831554961
2394931675268
2395122113.3110
239522243332.227
239532252788.730
239542255690.834
239552264199.134
2395622687137
2395722706441
23961310644150
2396231087675
2396331104479
23964311410083
2396531401993
2396631501793
2396731554798
23968316329100
239712976522
2397229861208
23973299988016
2397430001696.216
239812471482.95
239822537193.623
239832594927
23991228944120
2399222939412
2399322997615
23994230214917
2399523085617
23996231186.920
2399723162224
2399823261.127
2399923301.128
239910233510033
2399112359226.638
240012976524
240022982411
2400329861234
24004299988016
2400530032866.619
240112492414
240122496268.43
240212536758
240312522445
240412721856
240422808037
2405126381379
240612721855
2406227253.34
2406327612619
2406427826231
240712721855
2407227528618
2407327612621
240812751613
240822761261
2408327831010
24091281068
2410129764610
241022982405
2410329861206
241042995688
2410530032866.615
2410630511221
241113082812
2411230862082
2411330972.26
2411430993.37
241153101738
2411631064511
2411731127217
2411831237517
2411931248417
2411103127488.418
24111131334323
24111231431524
24121310646170
2412231149868
24123312371.568
24124312749272
2412531341875
2412631392079
2412731431680
2412831633092
2412931675494
24131310877200
2413231127540
2413331173544
24134312749244
2413531294645
2413631554762
2413731633066
2414132081.18
241423216307
241433220419
2414432343911
241453246212.318
241463253206.823
2414732605024
241512751625
2416128704.410
2416228783401
2417128704.49
2417229765137
2418130827515
24182309018712
2418330972.213
2418431104520
2418531402031
2418631501737
24191310646150
2419231149945
24193312371.548
2419431294357
2419531334561
2419631501769
2419731554772
2419831653576
2419931675481
24201310646110
2420231104611
24203311410115
2420431237920
24205312749622
2420631334829
2420731401934
2420831431539
2420931633045
242010317113247
24211310646160
24212310878160
24213311272164
24214311741165
24215312380168
24216312943172
24217314315176
24218315017176
24219315543185
2422131064618
242223117415
24223312371.55
2422431274969
2422531334611
2422631501725
2422731554329
2422831633035
2422931675439
242313220398
242323224323
242333245214.513
242343246212.314
2423532512616
2423632587821
2423732906533
24241335069311
2424233545419
24243335911112
242513501492.83
24252351192
2425335151.14
2426131932.26
2426232163011
2426332343418
242643248212.326
2426532522529
24271243017312
2427224391211
2427324574.46
242742464666
242752470766
242762496268.419
2427725224022
242813106427
242823108761
2428331141015
242843117416
242853123808
24286312749812
2428731334812
2428831431613
2428931501716
2428103170145.224
24281131738628
24291310642200
2429231087640
2429331104543
2429431237946
24295312749749
2429631334652
2429731392154
2429831501755
2429931633063
24291031653667
2430133506936
243023353454.35
24303335911110
2430433629410
243053501492.843
2431130972.23
243123106481
2431331141013
243143117417
2431531274989
2431631294411
243212976493
243222982432
2432329861225
24324299988011
243311910136
2434122113.381
243422236949.384
24343224546286
243442252788.787
243452254408.192
243462257371.894
24347226875104
2435122894835
243522299754
24353231186.98
2435423162110
2435523231812
2435623343.314
2435723392519
2435823502341.924
2435923657533
2436132081.18
243623209132
243633216303
243643224326
243653245214.516
2436632502718
2436732563618
2436832906324
243712423838
243722430157.34
2437324574.417
2437424627619
2437524646421
243762496268.435
243812995693
24382300017483
243911797316.89
243921806454
243931820549
2439418221433.313
2440122894819
244022293982
2440323021502
24404231186.97
2440523222310
2440623301.113
2440723343.315
244082337270.619
2440923392523
24401023502341.924
2440112359226.628
244112536809
244122537193.67
24421240212726
244222410350.921
2442324186023
24424242214425
24425243017328
244262439115.530
244272459624.840
2442824678044
244313106443
2443231141012
244333124826
2443431392012
2443531431517
2443631501817
2443731554321
2443831653631
24441311736110
244423127488.488
2444331334390
2444431392193
2444531401995
2444631431597
24447315017100
24448315543104
24449316537112
244410317237112
244411318263115
244512270665
244522278493
2445322939711
2445422997214
2445523119524
2445623192527
2445723261.128
2446122894847
2446223261.134
2446323301.136
244642337270.637
2446523502341.939
244712264199.129
24472226629723
24473227212124
2447422785025
2447522939734
2447622997635
244772302133.137
2447823085440
2447923119344
244813106443
244823114990
2448331334211
2448431341714
2448531392015
2448631431616
244912522432
2450131911.14
2450231932.23
245033197445
2450432162911
2450532204114
2450632243216
245111910139
245121948470.822
24521311738140
2452231392010
2452331431512
2452431501713
2452531554413
2452631653418
245273170145.220
2452831723720
2452931738023
245312492433
24541228943120
245422293990
245432299713
2454423085512
2454523162113
2454623231816
2454723343.318
245512471482.93
245522496268.432
2455325367554
245612522405
245622537193.619
2457131087236
2457231237914
245733127488.417
2457431501727
2457531554432
245763170145.242
2457731723645
24581311738140
24582312379112
245833127488.4114
24584313417115
24585314315129
24586316332142

Monthly Sales Representative Performance
In this problem, company sales representatives are responsible for working with customers to generate sales through customer order submissions. Company management wishes to understand sales representative performance on a monthly basis by examining the number of orders placed by customers through each sales representative and the corresponding product quantities and sales. Management has also expressed it’s important to highlight and understand those months where sales representatives were not involved in any customer order submissions. Given this problem, let’s get started.

We’ll start off with simply generating the data used to fill the temporal gaps. This is important because data is generated when a customer submits an order, not when they do not, so we’ll need to take the necessary steps to ensure months where a sales representative was inactive are included in the data. This data generation process relies on using a recursive common table expression (CTE). To follow along, it is not required to be familiar with the concept; however, if you’d like to read more on recursive common table expressions, see the recursion section.

Generating the Data
The recursive CTE below returns one row per sales representative and month combination for those months between the month of the first order and most recent order submitted. Both date endpoints are included. By specifying a fixed starting point and a dynamic end point for reporting month values, we can ensure the minimal number of rows are generated and our code dedicated to capturing the most recent reporting month is not hardcoded. Hardcoding the end point would require manual intervention for each month that passes. That wouldn’t be ideal as it would increase the cost of maintaining the solution. An additional optimization could be implemented by generating reporting month values for sales representatives starting with their individual hire dates instead of starting with the date of the first order submitted. This page is meant to go in-depth on employing low-maintenance and/or optimized solutions, so let’s carry on.

WITH calendar (reporting_month) AS (
    SELECT
    	TRUNC(MIN(oe.orders.order_date), 'MONTH')
    FROM
    	oe.orders
    UNION ALL
    SELECT
    	ADD_MONTHS(calendar.reporting_month, 1)
    FROM
    	calendar
    WHERE
    	calendar.reporting_month < (
    	SELECT
    		TRUNC(MAX(oe.orders.order_date), 'MONTH')
    	FROM
    		oe.orders
    )
),
sales_representative AS (
    SELECT
    	DISTINCT oe.orders.sales_rep_id
    FROM
    	oe.orders
    WHERE
    	oe.orders.sales_rep_id IS NOT NULL
)
SELECT
	sales_representative.sales_rep_id,
    calendar.reporting_month
FROM
	calendar
    CROSS JOIN
    sales_representative;
sales_rep_idreporting_month
1532004-03-01
1532004-04-01
1532004-05-01
1532004-06-01
1532004-07-01
1532004-08-01
1532004-09-01
1532004-10-01
1532004-11-01
1532004-12-01
1532005-01-01
1532005-02-01
1532005-03-01
1532005-04-01
1532005-05-01
1532005-06-01
1532005-07-01
1532005-08-01
1532005-09-01
1532005-10-01
1532005-11-01
1532005-12-01
1532006-01-01
1532006-02-01
1532006-03-01
1532006-04-01
1532006-05-01
1532006-06-01
1532006-07-01
1532006-08-01
1532006-09-01
1532006-10-01
1532006-11-01
1532006-12-01
1532007-01-01
1532007-02-01
1532007-03-01
1532007-04-01
1532007-05-01
1532007-06-01
1532007-07-01
1532007-08-01
1532007-09-01
1532007-10-01
1532007-11-01
1532007-12-01
1532008-01-01
1532008-02-01
1532008-03-01
1532008-04-01
1532008-05-01
1532008-06-01
1532008-07-01
1532008-08-01
1542004-03-01
1542004-04-01
1542004-05-01
1542004-06-01
1542004-07-01
1542004-08-01
1542004-09-01
1542004-10-01
1542004-11-01
1542004-12-01
1542005-01-01
1542005-02-01
1542005-03-01
1542005-04-01
1542005-05-01
1542005-06-01
1542005-07-01
1542005-08-01
1542005-09-01
1542005-10-01
1542005-11-01
1542005-12-01
1542006-01-01
1542006-02-01
1542006-03-01
1542006-04-01
1542006-05-01
1542006-06-01
1542006-07-01
1542006-08-01
1542006-09-01
1542006-10-01
1542006-11-01
1542006-12-01
1542007-01-01
1542007-02-01
1542007-03-01
1542007-04-01
1542007-05-01
1542007-06-01
1542007-07-01
1542007-08-01
1542007-09-01
1542007-10-01
1542007-11-01
1542007-12-01
1542008-01-01
1542008-02-01
1542008-03-01
1542008-04-01
1542008-05-01
1542008-06-01
1542008-07-01
1542008-08-01
1552004-03-01
1552004-04-01
1552004-05-01
1552004-06-01
1552004-07-01
1552004-08-01
1552004-09-01
1552004-10-01
1552004-11-01
1552004-12-01
1552005-01-01
1552005-02-01
1552005-03-01
1552005-04-01
1552005-05-01
1552005-06-01
1552005-07-01
1552005-08-01
1552005-09-01
1552005-10-01
1552005-11-01
1552005-12-01
1552006-01-01
1552006-02-01
1552006-03-01
1552006-04-01
1552006-05-01
1552006-06-01
1552006-07-01
1552006-08-01
1552006-09-01
1552006-10-01
1552006-11-01
1552006-12-01
1552007-01-01
1552007-02-01
1552007-03-01
1552007-04-01
1552007-05-01
1552007-06-01
1552007-07-01
1552007-08-01
1552007-09-01
1552007-10-01
1552007-11-01
1552007-12-01
1552008-01-01
1552008-02-01
1552008-03-01
1552008-04-01
1552008-05-01
1552008-06-01
1552008-07-01
1552008-08-01
1562004-03-01
1562004-04-01
1562004-05-01
1562004-06-01
1562004-07-01
1562004-08-01
1562004-09-01
1562004-10-01
1562004-11-01
1562004-12-01
1562005-01-01
1562005-02-01
1562005-03-01
1562005-04-01
1562005-05-01
1562005-06-01
1562005-07-01
1562005-08-01
1562005-09-01
1562005-10-01
1562005-11-01
1562005-12-01
1562006-01-01
1562006-02-01
1562006-03-01
1562006-04-01
1562006-05-01
1562006-06-01
1562006-07-01
1562006-08-01
1562006-09-01
1562006-10-01
1562006-11-01
1562006-12-01
1562007-01-01
1562007-02-01
1562007-03-01
1562007-04-01
1562007-05-01
1562007-06-01
1562007-07-01
1562007-08-01
1562007-09-01
1562007-10-01
1562007-11-01
1562007-12-01
1562008-01-01
1562008-02-01
1562008-03-01
1562008-04-01
1562008-05-01
1562008-06-01
1562008-07-01
1562008-08-01
1582004-03-01
1582004-04-01
1582004-05-01
1582004-06-01
1582004-07-01
1582004-08-01
1582004-09-01
1582004-10-01
1582004-11-01
1582004-12-01
1582005-01-01
1582005-02-01
1582005-03-01
1582005-04-01
1582005-05-01
1582005-06-01
1582005-07-01
1582005-08-01
1582005-09-01
1582005-10-01
1582005-11-01
1582005-12-01
1582006-01-01
1582006-02-01
1582006-03-01
1582006-04-01
1582006-05-01
1582006-06-01
1582006-07-01
1582006-08-01
1582006-09-01
1582006-10-01
1582006-11-01
1582006-12-01
1582007-01-01
1582007-02-01
1582007-03-01
1582007-04-01
1582007-05-01
1582007-06-01
1582007-07-01
1582007-08-01
1582007-09-01
1582007-10-01
1582007-11-01
1582007-12-01
1582008-01-01
1582008-02-01
1582008-03-01
1582008-04-01
1582008-05-01
1582008-06-01
1582008-07-01
1582008-08-01
1592004-03-01
1592004-04-01
1592004-05-01
1592004-06-01
1592004-07-01
1592004-08-01
1592004-09-01
1592004-10-01
1592004-11-01
1592004-12-01
1592005-01-01
1592005-02-01
1592005-03-01
1592005-04-01
1592005-05-01
1592005-06-01
1592005-07-01
1592005-08-01
1592005-09-01
1592005-10-01
1592005-11-01
1592005-12-01
1592006-01-01
1592006-02-01
1592006-03-01
1592006-04-01
1592006-05-01
1592006-06-01
1592006-07-01
1592006-08-01
1592006-09-01
1592006-10-01
1592006-11-01
1592006-12-01
1592007-01-01
1592007-02-01
1592007-03-01
1592007-04-01
1592007-05-01
1592007-06-01
1592007-07-01
1592007-08-01
1592007-09-01
1592007-10-01
1592007-11-01
1592007-12-01
1592008-01-01
1592008-02-01
1592008-03-01
1592008-04-01
1592008-05-01
1592008-06-01
1592008-07-01
1592008-08-01
1602004-03-01
1602004-04-01
1602004-05-01
1602004-06-01
1602004-07-01
1602004-08-01
1602004-09-01
1602004-10-01
1602004-11-01
1602004-12-01
1602005-01-01
1602005-02-01
1602005-03-01
1602005-04-01
1602005-05-01
1602005-06-01
1602005-07-01
1602005-08-01
1602005-09-01
1602005-10-01
1602005-11-01
1602005-12-01
1602006-01-01
1602006-02-01
1602006-03-01
1602006-04-01
1602006-05-01
1602006-06-01
1602006-07-01
1602006-08-01
1602006-09-01
1602006-10-01
1602006-11-01
1602006-12-01
1602007-01-01
1602007-02-01
1602007-03-01
1602007-04-01
1602007-05-01
1602007-06-01
1602007-07-01
1602007-08-01
1602007-09-01
1602007-10-01
1602007-11-01
1602007-12-01
1602008-01-01
1602008-02-01
1602008-03-01
1602008-04-01
1602008-05-01
1602008-06-01
1602008-07-01
1602008-08-01
1612004-03-01
1612004-04-01
1612004-05-01
1612004-06-01
1612004-07-01
1612004-08-01
1612004-09-01
1612004-10-01
1612004-11-01
1612004-12-01
1612005-01-01
1612005-02-01
1612005-03-01
1612005-04-01
1612005-05-01
1612005-06-01
1612005-07-01
1612005-08-01
1612005-09-01
1612005-10-01
1612005-11-01
1612005-12-01
1612006-01-01
1612006-02-01
1612006-03-01
1612006-04-01
1612006-05-01
1612006-06-01
1612006-07-01
1612006-08-01
1612006-09-01
1612006-10-01
1612006-11-01
1612006-12-01
1612007-01-01
1612007-02-01
1612007-03-01
1612007-04-01
1612007-05-01
1612007-06-01
1612007-07-01
1612007-08-01
1612007-09-01
1612007-10-01
1612007-11-01
1612007-12-01
1612008-01-01
1612008-02-01
1612008-03-01
1612008-04-01
1612008-05-01
1612008-06-01
1612008-07-01
1612008-08-01
1632004-03-01
1632004-04-01
1632004-05-01
1632004-06-01
1632004-07-01
1632004-08-01
1632004-09-01
1632004-10-01
1632004-11-01
1632004-12-01
1632005-01-01
1632005-02-01
1632005-03-01
1632005-04-01
1632005-05-01
1632005-06-01
1632005-07-01
1632005-08-01
1632005-09-01
1632005-10-01
1632005-11-01
1632005-12-01
1632006-01-01
1632006-02-01
1632006-03-01
1632006-04-01
1632006-05-01
1632006-06-01
1632006-07-01
1632006-08-01
1632006-09-01
1632006-10-01
1632006-11-01
1632006-12-01
1632007-01-01
1632007-02-01
1632007-03-01
1632007-04-01
1632007-05-01
1632007-06-01
1632007-07-01
1632007-08-01
1632007-09-01
1632007-10-01
1632007-11-01
1632007-12-01
1632008-01-01
1632008-02-01
1632008-03-01
1632008-04-01
1632008-05-01
1632008-06-01
1632008-07-01
1632008-08-01

In the result set above, there exists 486 rows. Why? There are nine sales representatives and 54 months between March 2004 and August 2008. In other words, one row per sales representative and reporting month combination. We’ll use this output as a template where the existing sales data for each sales representative will be populated. Before we can do that, we must first develop a query to capture this data for each sales representative.

Capturing Monthly Sales Data
Below is the query we’ll use to gather the number of orders, product quantities, and sales totals corresponding to each sales representative and order month.

WITH monthly_sales_summary AS (
    SELECT
		oe.orders.sales_rep_id,
        TRUNC(oe.orders.order_date, 'MONTH') AS order_month,
		COUNT(DISTINCT oe.orders.order_id) AS order_count,
        SUM(oe.order_items.quantity) AS quantity_total,
        SUM(oe.order_items.quantity * oe.order_items.unit_price) AS sales_total
    FROM
        oe.orders
        INNER JOIN
        oe.order_items
            ON oe.orders.order_id = oe.order_items.order_id
        	AND oe.orders.sales_rep_id IS NOT NULL
    GROUP BY
		oe.orders.sales_rep_id,
        TRUNC(oe.orders.order_date, 'MONTH')
)
SELECT
	monthly_sales_summary.sales_rep_id,
    monthly_sales_summary.order_month,
    monthly_sales_summary.order_count,
    monthly_sales_summary.quantity_total,
    monthly_sales_summary.sales_total
FROM
	monthly_sales_summary;
sales_rep_idorder_monthorder_countquantity_totalsales_total
1632007-07-0117969.2
1552007-07-011111677727.2
1612008-07-01129133893.6
1612007-05-01119817848.2
1632006-11-012335379.2
1602008-08-011162075.2
1632007-03-011461926.6
1542007-06-011848
1582007-06-012731697
1562007-05-01115215760.5
1612008-02-01113823431.9
1612007-06-011592854.2
1602007-11-01110810367.7
1542007-10-0111826653.4
1552008-01-011527826
1632006-09-01213819160.6
1592007-08-0113522150.1
1532007-10-0113129
1532007-08-01175278279.6
1562006-02-0118148070.6
1532007-11-0113213824
1542007-07-01213820
1632006-02-01131368501
1602007-03-013104261708
1582006-01-01136159872.4
1592007-10-01355663845.1
1542006-07-01234656117.9
1612007-07-013842199597.7
1532007-03-01110010794.6
1612007-11-01135125270.3
1542007-11-01271192408.2
1582006-03-01179866816
1612007-09-012723275046.6
1632004-03-0111285546.6
1552008-07-01176946257
1592007-04-011531636
1592007-07-01191233
1562008-05-01253668209.6
1582008-02-01147321863
1562007-08-01116270576.9
1542007-12-0113110474.6
1552007-06-012462605
1632007-09-0122710601
1592007-09-01115962303
1532007-12-01117611188.5
1612006-03-0115310
1542007-09-01165451
1602007-09-0118914087.5
1582006-07-0111125537.8
1632007-11-01212716165.3
1612006-02-01177134930
1582007-07-01143510
1612008-03-01150148552

Combining the Partial Solutions
Neither of the two queries above independently address management’s reporting requirements. We’ll need to combine the two queries by utilizing a LEFT JOIN. The result of the LEFT JOIN operation with the monthly_sales_template on the left and monthly_sales_summary on the right, is still one row per sales representative and reporting month combination; however, within those reporting months the monthly sales data for the corresponding sales representative is populated.

WITH calendar (reporting_month) AS (
    SELECT
    	TRUNC(MIN(oe.orders.order_date), 'MONTH')
    FROM
    	oe.orders
    UNION ALL
    SELECT
    	ADD_MONTHS(calendar.reporting_month, 1)
    FROM
    	calendar
    WHERE
    	calendar.reporting_month < (
    	SELECT
    		TRUNC(MAX(oe.orders.order_date), 'MONTH')
    	FROM
    		oe.orders
    )
),
sales_representative AS (
    SELECT
    	DISTINCT oe.orders.sales_rep_id
    FROM
    	oe.orders
    WHERE
    	oe.orders.sales_rep_id IS NOT NULL
),
monthly_sales_template AS (
	SELECT
		sales_representative.sales_rep_id,
		calendar.reporting_month
	FROM
		calendar
		CROSS JOIN
		sales_representative
),
monthly_sales_summary AS (
    SELECT
		oe.orders.sales_rep_id,
        TRUNC(oe.orders.order_date, 'MONTH') AS order_month,
		COUNT(DISTINCT oe.orders.sales_rep_id) AS order_count,
        SUM(oe.order_items.quantity) AS quantity_total,
        SUM(oe.order_items.quantity * oe.order_items.unit_price) AS sales_total
    FROM
        oe.orders
        INNER JOIN
        oe.order_items
            ON oe.orders.order_id = oe.order_items.order_id
        	AND oe.orders.sales_rep_id IS NOT NULL
    GROUP BY
		oe.orders.sales_rep_id,
        TRUNC(oe.orders.order_date, 'MONTH')
)
SELECT
	monthly_sales_template.sales_rep_id,
	monthly_sales_template.reporting_month,
    COALESCE(monthly_sales_summary.order_count, 0) AS order_count,
    COALESCE(monthly_sales_summary.quantity_total, 0) AS quantity_total,
    COALESCE(monthly_sales_summary.sales_total, 0) AS sales_total
FROM
	monthly_sales_template
	LEFT JOIN
	monthly_sales_summary
		ON monthly_sales_template.sales_rep_id = monthly_sales_summary.sales_rep_id
		AND monthly_sales_template.reporting_month = monthly_sales_summary.order_month
ORDER BY
    monthly_sales_template.sales_rep_id,
    monthly_sales_template.reporting_month;
sales_rep_idreporting_monthorder_countquantity_totalsales_total
1532004-03-01000
1532004-04-01000
1532004-05-01000
1532004-06-01000
1532004-07-01000
1532004-08-01000
1532004-09-01000
1532004-10-01000
1532004-11-01000
1532004-12-01000
1532005-01-01000
1532005-02-01000
1532005-03-01000
1532005-04-01000
1532005-05-01000
1532005-06-01000
1532005-07-01000
1532005-08-01000
1532005-09-01000
1532005-10-01000
1532005-11-01000
1532005-12-01000
1532006-01-01000
1532006-02-01000
1532006-03-01000
1532006-04-01000
1532006-05-01000
1532006-06-01000
1532006-07-01000
1532006-08-01000
1532006-09-01000
1532006-10-01000
1532006-11-01000
1532006-12-01000
1532007-01-01000
1532007-02-01000
1532007-03-01110010794.6
1532007-04-01000
1532007-05-01000
1532007-06-01000
1532007-07-01000
1532007-08-01175278279.6
1532007-09-01000
1532007-10-0113129
1532007-11-0113213824
1532007-12-01117611188.5
1532008-01-01000
1532008-02-01000
1532008-03-01000
1532008-04-01000
1532008-05-01000
1532008-06-01000
1532008-07-01000
1532008-08-01000
1542004-03-01000
1542004-04-01000
1542004-05-01000
1542004-06-01000
1542004-07-01000
1542004-08-01000
1542004-09-01000
1542004-10-01000
1542004-11-01000
1542004-12-01000
1542005-01-01000
1542005-02-01000
1542005-03-01000
1542005-04-01000
1542005-05-01000
1542005-06-01000
1542005-07-01000
1542005-08-01000
1542005-09-01000
1542005-10-01000
1542005-11-01000
1542005-12-01000
1542006-01-01000
1542006-02-01000
1542006-03-01000
1542006-04-01000
1542006-05-01000
1542006-06-01000
1542006-07-01134656117.9
1542006-08-01000
1542006-09-01000
1542006-10-01000
1542006-11-01000
1542006-12-01000
1542007-01-01000
1542007-02-01000
1542007-03-01000
1542007-04-01000
1542007-05-01000
1542007-06-011848
1542007-07-01113820
1542007-08-01000
1542007-09-01165451
1542007-10-0111826653.4
1542007-11-01171192408.2
1542007-12-0113110474.6
1542008-01-01000
1542008-02-01000
1542008-03-01000
1542008-04-01000
1542008-05-01000
1542008-06-01000
1542008-07-01000
1542008-08-01000
1552004-03-01000
1552004-04-01000
1552004-05-01000
1552004-06-01000
1552004-07-01000
1552004-08-01000
1552004-09-01000
1552004-10-01000
1552004-11-01000
1552004-12-01000
1552005-01-01000
1552005-02-01000
1552005-03-01000
1552005-04-01000
1552005-05-01000
1552005-06-01000
1552005-07-01000
1552005-08-01000
1552005-09-01000
1552005-10-01000
1552005-11-01000
1552005-12-01000
1552006-01-01000
1552006-02-01000
1552006-03-01000
1552006-04-01000
1552006-05-01000
1552006-06-01000
1552006-07-01000
1552006-08-01000
1552006-09-01000
1552006-10-01000
1552006-11-01000
1552006-12-01000
1552007-01-01000
1552007-02-01000
1552007-03-01000
1552007-04-01000
1552007-05-01000
1552007-06-011462605
1552007-07-011111677727.2
1552007-08-01000
1552007-09-01000
1552007-10-01000
1552007-11-01000
1552007-12-01000
1552008-01-011527826
1552008-02-01000
1552008-03-01000
1552008-04-01000
1552008-05-01000
1552008-06-01000
1552008-07-01176946257
1552008-08-01000
1562004-03-01000
1562004-04-01000
1562004-05-01000
1562004-06-01000
1562004-07-01000
1562004-08-01000
1562004-09-01000
1562004-10-01000
1562004-11-01000
1562004-12-01000
1562005-01-01000
1562005-02-01000
1562005-03-01000
1562005-04-01000
1562005-05-01000
1562005-06-01000
1562005-07-01000
1562005-08-01000
1562005-09-01000
1562005-10-01000
1562005-11-01000
1562005-12-01000
1562006-01-01000
1562006-02-0118148070.6
1562006-03-01000
1562006-04-01000
1562006-05-01000
1562006-06-01000
1562006-07-01000
1562006-08-01000
1562006-09-01000
1562006-10-01000
1562006-11-01000
1562006-12-01000
1562007-01-01000
1562007-02-01000
1562007-03-01000
1562007-04-01000
1562007-05-01115215760.5
1562007-06-01000
1562007-07-01000
1562007-08-01116270576.9
1562007-09-01000
1562007-10-01000
1562007-11-01000
1562007-12-01000
1562008-01-01000
1562008-02-01000
1562008-03-01000
1562008-04-01000
1562008-05-01153668209.6
1562008-06-01000
1562008-07-01000
1562008-08-01000
1582004-03-01000
1582004-04-01000
1582004-05-01000
1582004-06-01000
1582004-07-01000
1582004-08-01000
1582004-09-01000
1582004-10-01000
1582004-11-01000
1582004-12-01000
1582005-01-01000
1582005-02-01000
1582005-03-01000
1582005-04-01000
1582005-05-01000
1582005-06-01000
1582005-07-01000
1582005-08-01000
1582005-09-01000
1582005-10-01000
1582005-11-01000
1582005-12-01000
1582006-01-01136159872.4
1582006-02-01000
1582006-03-01179866816
1582006-04-01000
1582006-05-01000
1582006-06-01000
1582006-07-0111125537.8
1582006-08-01000
1582006-09-01000
1582006-10-01000
1582006-11-01000
1582006-12-01000
1582007-01-01000
1582007-02-01000
1582007-03-01000
1582007-04-01000
1582007-05-01000
1582007-06-011731697
1582007-07-01143510
1582007-08-01000
1582007-09-01000
1582007-10-01000
1582007-11-01000
1582007-12-01000
1582008-01-01000
1582008-02-01147321863
1582008-03-01000
1582008-04-01000
1582008-05-01000
1582008-06-01000
1582008-07-01000
1582008-08-01000
1592004-03-01000
1592004-04-01000
1592004-05-01000
1592004-06-01000
1592004-07-01000
1592004-08-01000
1592004-09-01000
1592004-10-01000
1592004-11-01000
1592004-12-01000
1592005-01-01000
1592005-02-01000
1592005-03-01000
1592005-04-01000
1592005-05-01000
1592005-06-01000
1592005-07-01000
1592005-08-01000
1592005-09-01000
1592005-10-01000
1592005-11-01000
1592005-12-01000
1592006-01-01000
1592006-02-01000
1592006-03-01000
1592006-04-01000
1592006-05-01000
1592006-06-01000
1592006-07-01000
1592006-08-01000
1592006-09-01000
1592006-10-01000
1592006-11-01000
1592006-12-01000
1592007-01-01000
1592007-02-01000
1592007-03-01000
1592007-04-011531636
1592007-05-01000
1592007-06-01000
1592007-07-01191233
1592007-08-0113522150.1
1592007-09-01115962303
1592007-10-01155663845.1
1592007-11-01000
1592007-12-01000
1592008-01-01000
1592008-02-01000
1592008-03-01000
1592008-04-01000
1592008-05-01000
1592008-06-01000
1592008-07-01000
1592008-08-01000
1602004-03-01000
1602004-04-01000
1602004-05-01000
1602004-06-01000
1602004-07-01000
1602004-08-01000
1602004-09-01000
1602004-10-01000
1602004-11-01000
1602004-12-01000
1602005-01-01000
1602005-02-01000
1602005-03-01000
1602005-04-01000
1602005-05-01000
1602005-06-01000
1602005-07-01000
1602005-08-01000
1602005-09-01000
1602005-10-01000
1602005-11-01000
1602005-12-01000
1602006-01-01000
1602006-02-01000
1602006-03-01000
1602006-04-01000
1602006-05-01000
1602006-06-01000
1602006-07-01000
1602006-08-01000
1602006-09-01000
1602006-10-01000
1602006-11-01000
1602006-12-01000
1602007-01-01000
1602007-02-01000
1602007-03-011104261708
1602007-04-01000
1602007-05-01000
1602007-06-01000
1602007-07-01000
1602007-08-01000
1602007-09-0118914087.5
1602007-10-01000
1602007-11-01110810367.7
1602007-12-01000
1602008-01-01000
1602008-02-01000
1602008-03-01000
1602008-04-01000
1602008-05-01000
1602008-06-01000
1602008-07-01000
1602008-08-011162075.2
1612004-03-01000
1612004-04-01000
1612004-05-01000
1612004-06-01000
1612004-07-01000
1612004-08-01000
1612004-09-01000
1612004-10-01000
1612004-11-01000
1612004-12-01000
1612005-01-01000
1612005-02-01000
1612005-03-01000
1612005-04-01000
1612005-05-01000
1612005-06-01000
1612005-07-01000
1612005-08-01000
1612005-09-01000
1612005-10-01000
1612005-11-01000
1612005-12-01000
1612006-01-01000
1612006-02-01177134930
1612006-03-0115310
1612006-04-01000
1612006-05-01000
1612006-06-01000
1612006-07-01000
1612006-08-01000
1612006-09-01000
1612006-10-01000
1612006-11-01000
1612006-12-01000
1612007-01-01000
1612007-02-01000
1612007-03-01000
1612007-04-01000
1612007-05-01119817848.2
1612007-06-011592854.2
1612007-07-011842199597.7
1612007-08-01000
1612007-09-011723275046.6
1612007-10-01000
1612007-11-01135125270.3
1612007-12-01000
1612008-01-01000
1612008-02-01113823431.9
1612008-03-01150148552
1612008-04-01000
1612008-05-01000
1612008-06-01000
1612008-07-01129133893.6
1612008-08-01000
1632004-03-0111285546.6
1632004-04-01000
1632004-05-01000
1632004-06-01000
1632004-07-01000
1632004-08-01000
1632004-09-01000
1632004-10-01000
1632004-11-01000
1632004-12-01000
1632005-01-01000
1632005-02-01000
1632005-03-01000
1632005-04-01000
1632005-05-01000
1632005-06-01000
1632005-07-01000
1632005-08-01000
1632005-09-01000
1632005-10-01000
1632005-11-01000
1632005-12-01000
1632006-01-01000
1632006-02-01131368501
1632006-03-01000
1632006-04-01000
1632006-05-01000
1632006-06-01000
1632006-07-01000
1632006-08-01000
1632006-09-01113819160.6
1632006-10-01000
1632006-11-011335379.2
1632006-12-01000
1632007-01-01000
1632007-02-01000
1632007-03-011461926.6
1632007-04-01000
1632007-05-01000
1632007-06-01000
1632007-07-0117969.2
1632007-08-01000
1632007-09-0112710601
1632007-10-01000
1632007-11-01112716165.3
1632007-12-01000
1632008-01-01000
1632008-02-01000
1632008-03-01000
1632008-04-01000
1632008-05-01000
1632008-06-01000
1632008-07-01000
1632008-08-01000

You’ll notice in months where the sales representative didn’t participate in any customer order submissions, I’ve decided to populate those row’s sales data with zeros using the COALESCE function. This is personal preference but may prove convenient if the data is plotted on a graph. Additionally, I’ve ordered the result set by sales representative and reporting month, allowing each representative’s performance to be viewed more easily when the focus is on a single sales representative.

With the output above, we’ve successfully met management’s reporting requirements. While the CROSS JOIN alone didn’t solve our problem, it played a key role by generating the monthly sales template required in subsequent steps.

Knowledge Check
If you’d like to confirm your understanding on JOINS and other fundamental concepts, consider solving a handful of my practice problems here.