$wpdb->prepare() looks like sprintf() and behaves differently in the one way that matters: %s adds the surrounding quotes itself. Writing them by hand produces a doubly-quoted value and a query that silently matches nothing.
// wrong — prepare quotes it, so the value becomes ''ada''
$wpdb->prepare( "WHERE name = '%s'", $name );
// right
$wpdb->prepare( "WHERE name = %s AND id = %d", $name, $id );
There are only three placeholders — %s, %d, %f — and a literal percent must be written %%, which bites on LIKE patterns. Table and column names cannot be parameterised at all, so anything dynamic there has to be validated against a whitelist rather than escaped. esc_sql() is not a substitute; it escapes but does not quote.