2 hrs ??? Actually I even don't expect it to take 6 mins with scan..endscan approach. SQLs use empty() which is not optimizable (I assume you had indexes on left(zip,5) and other - you might replace the !empty(trim(sddmdata.sdaddr)) expression with :
!(sddmdata.sdaddr == '') ).
scan approach does one single pass on one of tables (probably you'd want to choose 8500 recs one) and a do case check. It's almost equivalant to one 'optimized' SQL (preparation of indexes might take time - you might even skip that with one table usage with order set to left(zip,5) tag and do some locate while ...for ... But I think indexes + 3 use again would be faster).
You have unnecessary trimming in comparisons. Instead use set ansi and set exact. You might recover extra time doing so too (and possibly you dont need empty() at all).
Cetin