-- 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