The example query below will get you the specified result set using MySQL, but it doesn't really do "fuzzy matching", at least, that's not how I would describe the algorithm. (This implements the algorithm you describe -- sorting by values, and then checking each value to see if the leading portion "matches" a previously retrieved value.)
This finds an "exact match" of the leading portion of the neighborhood value against the value from previously retrieved rows, there's not really any "fuzziness" about the match.
When the query encounters a value that is "unmatched", it marks that value is "unmatched". For the next value retrieved, it checks whether that value starts with the previously "unmatched" value; if the leading portion of the string is an exact match, the value is discarded. Otherwise, the value is marked as an "unmatched" value, and is kept.
This approach uses inline views (or "derived tables" as MySQL refers to them). The innermost inline view (aliased as s) gets us a sorted list of distinct values for neighborhood. The "trick" (if you want to call it that) is in the next inline view (aliased as "t") where we make use of MySQL user variables to reference a previously retrieved value.
To avoid any issues with "special characters", we do an equality comparison on the leading characters.
Here's the whole query:
SELECT t.neighborhood
FROM (
SELECT IF(IFNULL(LEFT(s.neighborhood,CHAR_LENGTH(@match)) <> @match,1),@match := s.neighborhood,NULL) AS neighborhood
FROM (SELECT RTRIM(neighborhood) AS neighborhood
FROM mytable
JOIN (SELECT @match := NULL) r
GROUP BY neighborhood
ORDER BY neighborhood
) s
) t
WHERE t.neighborhood IS NOT NULL
It's all really pretty straightforward, except for the initialization of the @match variable, and the expression that performs the comparison of the current value to a previous value.
If we aren't concerned with the corner cases introduced by special characters in the values, we can use a simpler LIKE or REGEXP to do the comparison:
s.neighborhood NOT LIKE CONCAT(@match,'%')
s.neighborhood NOT REGEXP CONCAT('^',@match)
The LIKE operator is subject to the underscore and percent characters, the REGEXP is subject to special characters used in regular expressions. To avoid those issue, the query above uses a comparison that is a bit more unwieldy looking:
LEFT(s.neighborhood,CHAR_LENGTH(@match)) <> @match
What that's doing is taking the previous value (e.g. @match := 'Park View') and comparing that to the leading portion (up to the length of 'Park View') of the next value, do determine whether it's a match.
One benefit of the approach with this query is that the values returned are guaranteed tp "match" in a predicate in a subsequent query. Say you're using this query to get a list of neighborhoods, and the user has selected one. This is going to return a set of values that will "match" to each and every row.
A subsequent query can use any of the returned values in a simple predicate (WHERE clause) to return rows that match. For example, if the user has selected the value 'Great Lake':
SELECT t.*
FROM mytable t
WHERE LEFT(t.neighborhood,CHAR_LENGTH('Great Lake') = 'Great Lake'
In the case where we used a LIKE or REGEXP predicate to match, we'd want to use the corresponding match in the predicate of the subsequent query:
SELECT t.*
FROM mytable t
WHERE t.neighborhood LIKE CONCAT('Great Lake','%')
SELECT t.*
FROM mytable t
WHERE t.neighborhood REGEXP CONCAT('^','Great Lake')
ONLY return "Park View" and "Great Lake".
" - that is the expected output. – Turn