EXISTS (subquery) is true when the subquery returns at least one row. It answers "is there any...?" questions:
SELECT c.first_name
FROM customers AS c
WHERE EXISTS (SELECT 1 FROM tickets AS t WHERE t.customer_id = c.customer_id);
What the subquery selects doesn't matter, so SELECT 1 is the convention. NOT EXISTS keeps the rows with no match.
IN (subquery) often gives the same result, but NOT IN has a trap: if the list contains a NULL, x NOT IN (...) is never true, and the query returns nothing. NOT EXISTS doesn't have this problem, which is why many teams use it for "has no..." questions.
Unlike a join, EXISTS never duplicates rows: a customer with five tickets still appears once.