Skip to content

Commit a123b89

Browse files
authored
Merge branch 'main' into docs
2 parents 4745422 + c4c6199 commit a123b89

19 files changed

+3754
-495
lines changed
3.18 MB
Loading
3.56 MB
Loading
1.29 MB
Loading
1.48 MB
Loading
1.56 MB
Loading
866 KB
Loading
130 KB
Loading

docs/sql/SQL-joins/cross-join.md

Lines changed: 378 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,378 @@
1+
---
2+
id: cross-join
3+
title: SQL CROSS JOIN #Remember to keep this unique, as it maps with giscus discussions in the recodehive/support/general discussions
4+
sidebar_label: CROSS JOIN #displays in sidebar
5+
sidebar_position: 6
6+
tags:
7+
[
8+
sql,
9+
cross join,
10+
sql cross join,
11+
cartesian product,
12+
join tables,
13+
relational database,
14+
sql tutorial,
15+
database queries,
16+
]
17+
description: Learn about SQL CROSS JOIN, how it creates Cartesian products, syntax, examples, and when to use it for generating all possible combinations.
18+
---
19+
20+
## What is CROSS JOIN?
21+
22+
SQL **CROSS JOIN** produces the Cartesian product of two tables, returning all possible combinations of rows from both tables. Unlike other joins, CROSS JOIN doesn't require a join condition and combines every row from the first table with every row from the second table.
23+
24+
:::note
25+
**Key Characteristics of CROSS JOIN:**
26+
27+
- **Cartesian Product**: Creates all possible row combinations from both tables.
28+
29+
- **No Join Condition**: Doesn't use ON or WHERE clauses for joining logic.
30+
31+
- **Result Size**: Returns (Table1 rows × Table2 rows) total rows.
32+
33+
- **Use With Caution**: Can quickly generate enormous result sets.
34+
:::
35+
36+
<BrowserWindow url="https://github.com" bodyStyle={{padding: 0}}>
37+
[![GitHub](./assets/cross-join.gif)](https://www.learnsqlonline.org/)
38+
</BrowserWindow>
39+
40+
:::success
41+
**When to Use CROSS JOIN:**
42+
43+
- **Generating Combinations**: Creating all possible product-color combinations
44+
- **Time Series Data**: Pairing dates with entities for complete time series
45+
- **Report Templates**: Creating report structures with all possible categories
46+
- **Test Data Generation**: Creating comprehensive test datasets
47+
- **Mathematical Operations**: Matrix operations and mathematical calculations
48+
49+
**Real-World Example:**
50+
A clothing retailer wants to create a product catalog showing all possible combinations of shirt styles (5 types) with available colors (8 colors), resulting in 40 unique product variants.
51+
:::
52+
53+
:::warning
54+
**⚠️ Important Considerations:**
55+
56+
CROSS JOIN can produce **very large result sets**:
57+
- 1,000 rows × 1,000 rows = 1,000,000 rows
58+
- 10,000 rows × 5,000 rows = 50,000,000 rows
59+
60+
Always consider the size of your tables before using CROSS JOIN!
61+
:::
62+
63+
:::info
64+
65+
## Basic CROSS JOIN Syntax
66+
67+
```sql
68+
-- Method 1: Using CROSS JOIN keyword
69+
SELECT column1, column2, ...
70+
FROM table1
71+
CROSS JOIN table2;
72+
73+
-- Method 2: Using comma-separated tables (implicit cross join)
74+
SELECT column1, column2, ...
75+
FROM table1, table2;
76+
```
77+
78+
| **Component** | **Purpose** | **Example** |
79+
|---------------|-------------|-------------|
80+
| SELECT | Choose columns to display | `SELECT p.name, c.color_name` |
81+
| FROM | First table | `FROM products p` |
82+
| CROSS JOIN | Second table | `CROSS JOIN colors c` |
83+
84+
## Result Set Size Calculation
85+
86+
| **Table 1 Rows** | **Table 2 Rows** | **Result Rows** |
87+
|-------------------|-------------------|-----------------|
88+
| 3 | 4 | 12 |
89+
| 10 | 5 | 50 |
90+
| 100 | 20 | 2,000 |
91+
| 1,000 | 1,000 | 1,000,000 |
92+
93+
:::
94+
95+
## Practical Examples
96+
97+
<Tabs>
98+
<TabItem value="Basic Example">
99+
```sql
100+
-- Create all possible product-color combinations
101+
SELECT
102+
p.product_id,
103+
p.product_name,
104+
p.base_price,
105+
c.color_id,
106+
c.color_name,
107+
c.color_hex,
108+
(p.base_price + c.price_adjustment) AS final_price
109+
FROM products p
110+
CROSS JOIN colors c
111+
WHERE p.category = 'Shirts'
112+
ORDER BY p.product_name, c.color_name;
113+
114+
-- Result: Every shirt paired with every available color
115+
```
116+
</TabItem>
117+
<TabItem value="Time Series Generation">
118+
```sql
119+
-- Generate complete date series for all employees
120+
SELECT
121+
e.employee_id,
122+
e.employee_name,
123+
e.department,
124+
d.date_value,
125+
YEAR(d.date_value) AS year,
126+
MONTH(d.date_value) AS month,
127+
'Pending' AS attendance_status
128+
FROM employees e
129+
CROSS JOIN (
130+
SELECT DATE('2024-01-01') + INTERVAL (a.a + (10 * b.a)) DAY AS date_value
131+
FROM (SELECT 0 AS a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
132+
UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) a,
133+
(SELECT 0 AS a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
134+
UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
135+
UNION SELECT 10 UNION SELECT 11 UNION SELECT 12 UNION SELECT 13
136+
UNION SELECT 14 UNION SELECT 15 UNION SELECT 16 UNION SELECT 17
137+
UNION SELECT 18 UNION SELECT 19 UNION SELECT 20 UNION SELECT 21
138+
UNION SELECT 22 UNION SELECT 23 UNION SELECT 24 UNION SELECT 25
139+
UNION SELECT 26 UNION SELECT 27 UNION SELECT 28 UNION SELECT 29
140+
UNION SELECT 30 UNION SELECT 31 UNION SELECT 32 UNION SELECT 33
141+
UNION SELECT 34 UNION SELECT 35 UNION SELECT 36) b
142+
WHERE DATE('2024-01-01') + INTERVAL (a.a + (10 * b.a)) DAY <= '2024-12-31'
143+
) d
144+
WHERE e.status = 'Active'
145+
ORDER BY e.employee_id, d.date_value;
146+
```
147+
</TabItem>
148+
<TabItem value="Product Configuration">
149+
```sql
150+
-- Generate all possible product configurations
151+
SELECT
152+
p.product_name,
153+
s.size_name,
154+
s.size_multiplier,
155+
c.color_name,
156+
m.material_name,
157+
m.material_cost,
158+
CONCAT(p.product_name, ' - ', s.size_name, ' - ', c.color_name, ' - ', m.material_name) AS sku_description,
159+
(p.base_price * s.size_multiplier + c.price_adjustment + m.material_cost) AS final_price
160+
FROM products p
161+
CROSS JOIN sizes s
162+
CROSS JOIN colors c
163+
CROSS JOIN materials m
164+
WHERE p.category = 'Custom Items'
165+
AND s.available = 1
166+
AND c.available = 1
167+
AND m.available = 1
168+
ORDER BY p.product_name, final_price DESC;
169+
```
170+
</TabItem>
171+
<TabItem value="Sales Territory Matrix">
172+
```sql
173+
-- Create sales target matrix for all reps in all territories
174+
SELECT
175+
sr.rep_id,
176+
sr.rep_name,
177+
t.territory_id,
178+
t.territory_name,
179+
t.region,
180+
t.base_target,
181+
sr.experience_level,
182+
CASE sr.experience_level
183+
WHEN 'Senior' THEN t.base_target * 1.2
184+
WHEN 'Mid-level' THEN t.base_target * 1.0
185+
WHEN 'Junior' THEN t.base_target * 0.8
186+
END AS adjusted_target,
187+
CONCAT(sr.rep_name, ' - ', t.territory_name) AS assignment_code
188+
FROM sales_reps sr
189+
CROSS JOIN territories t
190+
WHERE sr.status = 'Active'
191+
AND t.status = 'Open'
192+
ORDER BY t.region, sr.experience_level DESC, adjusted_target DESC;
193+
```
194+
</TabItem>
195+
<TabItem value="Menu Combinations">
196+
```sql
197+
-- Restaurant menu: all possible meal combinations
198+
SELECT
199+
a.item_name AS appetizer,
200+
a.price AS appetizer_price,
201+
m.item_name AS main_course,
202+
m.price AS main_price,
203+
d.item_name AS dessert,
204+
d.price AS dessert_price,
205+
(a.price + m.price + d.price) AS combo_price,
206+
(a.price + m.price + d.price) * 0.9 AS discounted_price,
207+
CONCAT(a.item_name, ' + ', m.item_name, ' + ', d.item_name) AS combo_name
208+
FROM menu_items a
209+
CROSS JOIN menu_items m
210+
CROSS JOIN menu_items d
211+
WHERE a.category = 'Appetizer'
212+
AND m.category = 'Main Course'
213+
AND d.category = 'Dessert'
214+
AND a.available = 1
215+
AND m.available = 1
216+
AND d.available = 1
217+
HAVING combo_price <= 50 -- Filter expensive combinations
218+
ORDER BY combo_price;
219+
```
220+
</TabItem>
221+
<TabItem value="Sample Output">
222+
```plaintext
223+
-- Sample result for product-color cross join:
224+
225+
product_id | product_name | base_price | color_id | color_name | final_price
226+
-----------|-----------------|------------|----------|------------|------------
227+
1 | Classic T-Shirt | 19.99 | 1 | Red | 21.99
228+
1 | Classic T-Shirt | 19.99 | 2 | Blue | 21.99
229+
1 | Classic T-Shirt | 19.99 | 3 | Green | 21.99
230+
1 | Classic T-Shirt | 19.99 | 4 | Black | 22.99
231+
2 | Premium Polo | 39.99 | 1 | Red | 41.99
232+
2 | Premium Polo | 39.99 | 2 | Blue | 41.99
233+
2 | Premium Polo | 39.99 | 3 | Green | 41.99
234+
2 | Premium Polo | 39.99 | 4 | Black | 42.99
235+
236+
-- Note: Every product appears with every color
237+
-- 2 products × 4 colors = 8 total combinations
238+
```
239+
</TabItem>
240+
</Tabs>
241+
242+
## Advanced CROSS JOIN Patterns
243+
244+
:::tip
245+
**Complex Scenarios:**
246+
247+
1. **Filtered Cross Join**:
248+
```sql
249+
-- Create valid product combinations only
250+
SELECT
251+
p.product_name,
252+
c.color_name,
253+
s.size_name
254+
FROM products p
255+
CROSS JOIN colors c
256+
CROSS JOIN sizes s
257+
WHERE p.category = c.compatible_category
258+
AND s.size_group = p.size_group
259+
AND p.discontinued = 0;
260+
```
261+
262+
2. **Cross Join with Aggregation**:
263+
```sql
264+
-- Calculate distance matrix between all store locations
265+
SELECT
266+
s1.store_name AS from_store,
267+
s2.store_name AS to_store,
268+
SQRT(
269+
POW(s1.latitude - s2.latitude, 2) +
270+
POW(s1.longitude - s2.longitude, 2)
271+
) * 69 AS distance_miles -- Rough conversion
272+
FROM stores s1
273+
CROSS JOIN stores s2
274+
WHERE s1.store_id != s2.store_id -- Exclude same store
275+
ORDER BY distance_miles;
276+
```
277+
278+
3. **Time Series with Cross Join**:
279+
```sql
280+
-- Create complete monthly report template
281+
SELECT
282+
months.month_name,
283+
months.month_number,
284+
dept.department_name,
285+
dept.budget,
286+
0 AS actual_spending, -- Placeholder for actual data
287+
'Pending' AS status
288+
FROM (
289+
SELECT 1 as month_number, 'January' as month_name
290+
UNION SELECT 2, 'February' UNION SELECT 3, 'March'
291+
UNION SELECT 4, 'April' UNION SELECT 5, 'May'
292+
UNION SELECT 6, 'June' UNION SELECT 7, 'July'
293+
UNION SELECT 8, 'August' UNION SELECT 9, 'September'
294+
UNION SELECT 10, 'October' UNION SELECT 11, 'November'
295+
UNION SELECT 12, 'December'
296+
) months
297+
CROSS JOIN departments dept
298+
WHERE dept.active = 1
299+
ORDER BY dept.department_name, months.month_number;
300+
```
301+
:::
302+
303+
## Performance & Optimization
304+
305+
:::caution
306+
**Performance Considerations:**
307+
308+
1. **Result Set Size**: Always calculate expected result size before running
309+
2. **Memory Usage**: Large cross joins can consume significant memory
310+
3. **Processing Time**: Exponential growth in processing time with table size
311+
4. **Network Traffic**: Large result sets increase network overhead
312+
313+
**Optimization Strategies:**
314+
```sql
315+
-- Use LIMIT to test queries first
316+
SELECT p.product_name, c.color_name
317+
FROM products p
318+
CROSS JOIN colors c
319+
LIMIT 100; -- Test with small result set first
320+
321+
-- Use WHERE clauses to reduce combinations
322+
SELECT p.product_name, c.color_name
323+
FROM products p
324+
CROSS JOIN colors c
325+
WHERE p.category = 'Shirts'
326+
AND c.price_adjustment <= 5.00;
327+
328+
-- Consider using EXISTS instead for existence checks
329+
SELECT p.product_name
330+
FROM products p
331+
WHERE EXISTS (
332+
SELECT 1 FROM colors c
333+
WHERE c.compatible_category = p.category
334+
);
335+
```
336+
:::
337+
338+
## Best Practices & Guidelines
339+
340+
:::info
341+
**DO's and DON'Ts:**
342+
343+
**DO's:**
344+
- Calculate result set size before executing
345+
- Use WHERE clauses to limit combinations
346+
- Test with LIMIT first
347+
- Use for legitimate business scenarios (combinations, templates, etc.)
348+
- Consider alternatives like window functions or recursive CTEs
349+
350+
**DON'Ts:**
351+
- Use CROSS JOIN when other joins are more appropriate
352+
- Run unbounded CROSS JOINs on large tables
353+
- Use for simple data lookup operations
354+
- Forget to filter results when possible
355+
356+
**Good Practice Example:**
357+
```sql
358+
-- Responsible CROSS JOIN usage
359+
SELECT
360+
p.product_name,
361+
c.color_name,
362+
COUNT(*) OVER() AS total_combinations -- Show total for reference
363+
FROM products p
364+
CROSS JOIN colors c
365+
WHERE p.category = 'Customizable' -- Limit to relevant products
366+
AND c.available = 1 -- Only available colors
367+
AND p.launch_date <= CURRENT_DATE -- Only launched products
368+
LIMIT 1000; -- Safety limit
369+
```
370+
:::
371+
372+
373+
374+
## Conclusion
375+
376+
CROSS JOIN is a specialized tool that creates Cartesian products of tables. While powerful for generating combinations and creating comprehensive datasets, it must be used carefully due to its potential for creating extremely large result sets. Understanding when and how to use CROSS JOIN effectively will help you solve complex business problems involving combinations, permutations, and complete data templates.
377+
378+
<GiscusComments/>

0 commit comments

Comments
 (0)