Some prefer the Haversine formula because it gives better precision, but given that MySql's floating point precision is high enough, the difference between the two is negligible. The first one is simpler to implement:

Explanation

The distance calculation is used in the order by clause of the group_concat aggregation function, which results in a comma-separated list of cafe_id values in order of their distance to the cafe you group by. The substring_index function extracts the first item from that list.

The join condition is important as without it you'd get the cafe itself as the closest neighbor (its distance is obviously 0 then).