-- location_extract_place_fuzzy(string, stateAbbrev) -- This function checks the place_lookup table to find a potential match to -- the location described at the end of the given string. If an exact match -- fails, a fuzzy match is performed. The location as found in the given -- string is returned. CREATE OR REPLACE FUNCTION location_extract_place_fuzzy( fullStreet VARCHAR, stateAbbrev VARCHAR ) RETURNS VARCHAR AS $_$ DECLARE ws VARCHAR; tempString VARCHAR; location VARCHAR; tempInt INTEGER; word_count INTEGER; rec RECORD; test BOOLEAN; BEGIN ws := E'[ ,.\n\f\t]'; tempString := substring(fullStreet, '(?i)' || ws || '([a-zA-Z0-9]+)$'); IF tempString IS NULL THEN tempString := fullStreet; END IF; IF stateAbbrev IS NOT NULL THEN SELECT into tempInt count(*) FROM place_lookup WHERE place_lookup.state = stateAbbrev AND soundex(tempString) = end_soundex(name); ELSE SELECT into tempInt count(*) FROM place_lookup WHERE soundex(tempString) = end_soundex(name); END IF; IF tempInt > 0 THEN -- Some potentials were found. Begin a word-by-word soundex on each. tempInt := 50; IF stateAbbrev IS NOT NULL THEN FOR rec IN SELECT name FROM place_lookup WHERE place_lookup.state = stateAbbrev AND soundex(tempString) = end_soundex(name) LOOP word_count := count_words(rec.name); test := TRUE; tempString := get_last_words(fullStreet, word_count); FOR i IN 1..word_count LOOP IF soundex(split_part(tempString, ' ', i)) != soundex(split_part(rec.name, ' ', i)) THEN test := FALSE; END IF; END LOOP; IF test THEN -- The soundex matched, determine if the distance is better. IF levenshtein_ignore_case(rec.name, tempString) < tempInt THEN location := tempString; tempInt := levenshtein_ignore_case(rec.name, tempString); END IF; END IF; END LOOP; ELSE FOR rec IN SELECT name FROM place_lookup WHERE soundex(tempString) = end_soundex(name) LOOP word_count := count_words(rec.name); test := TRUE; tempString := get_last_words(fullStreet, word_count); FOR i IN 1..word_count LOOP IF soundex(split_part(tempString, ' ', i)) != soundex(split_part(rec.name, ' ', i)) THEN test := FALSE; END IF; END LOOP; IF test THEN -- The soundex matched, determine if the distance is better. IF levenshtein_ignore_case(rec.name, tempString) < tempInt THEN location := tempString; tempInt := levenshtein_ignore_case(rec.name, tempString); END IF; END IF; END LOOP; END IF; END IF; RETURN location; END; $_$ LANGUAGE plpgsql;