Spaces:
Sleeping
Sleeping
| -- Template: Self-Join for Hierarchical or Sequential Data | |
| -- Pattern: Join table to itself to find relationships within same table | |
| -- Use Case: Manager-employee, sequential orders, referrals, product recommendations | |
| -- Example 1: Find customers who ordered same product | |
| SELECT DISTINCT | |
| c1.customer_id as customer1, | |
| c1.name as customer1_name, | |
| c2.customer_id as customer2, | |
| c2.name as customer2_name, | |
| oi1.product_id, | |
| p.name as product_name | |
| FROM order_items oi1 | |
| JOIN order_items oi2 ON oi1.product_id = oi2.product_id | |
| AND oi1.order_id < oi2.order_id -- Avoid duplicates | |
| JOIN orders o1 ON oi1.order_id = o1.order_id | |
| JOIN orders o2 ON oi2.order_id = o2.order_id | |
| JOIN customers c1 ON o1.customer_id = c1.customer_id | |
| JOIN customers c2 ON o2.customer_id = c2.customer_id | |
| JOIN products p ON oi1.product_id = p.product_id | |
| WHERE c1.customer_id != c2.customer_id; | |
| -- Example 2: Find sequential orders by same customer | |
| SELECT | |
| c.name, | |
| o1.order_id as first_order, | |
| o1.order_date as first_date, | |
| o2.order_id as next_order, | |
| o2.order_date as next_date, | |
| o2.order_date - o1.order_date as days_between | |
| FROM orders o1 | |
| JOIN orders o2 ON o1.customer_id = o2.customer_id | |
| AND o2.order_date > o1.order_date | |
| JOIN customers c ON o1.customer_id = c.customer_id | |
| ORDER BY c.name, o1.order_date; | |
| -- Key Concepts: | |
| -- - Join table to itself with different aliases | |
| -- - Use inequality (< or !=) to avoid matching same row | |
| -- - Useful for finding patterns, sequences, or relationships | |
| -- - Can be combined with window functions for "next" or "previous" record |