It seems like the primary thread differentiator is the address (note how I did not say contact). The address column is a TEXT field and the number is saved as it is received. Code:sqlite> .schema sms CREATE TABLE sms (_id INTEGER PRIMARY KEY,thread_id INTEGER,address TEXT,person INTEGER,date INTEGER,date_sent INTEGER DEFAULT 0,protocol INTEGER,read INTEGER DEFAULT 0,status INTEGER DEFAULT -1,type INTEGER,reply_path_present INTEGER,subject TEXT,body TEXT,service_center TEXT,locked INTEGER DEFAULT 0,error_code INTEGER DEFAULT 0,seen INTEGER DEFAULT 0,timed INTEGER DEFAULT 0,deleted INTEGER DEFAULT 0,sync_state INTEGER DEFAULT 0,marker INTEGER DEFAULT 0,source TEXT,bind_id INTEGER DEFAULT 0,mx_status INTEGER DEFAULT 0,mx_id INTEGER,out_time INTEGER DEFAULT 0,account TEXT); CREATE INDEX mx_msgId_index_on_sms ON sms(mx_id); CREATE INDEX typeThreadIdIndex ON sms (type, thread_id); On multiple occasions whether it be because I was roaming at the time or I started a thread with a MMS I have had conversations with the same phone number split into multiple threads. This mostly happens when I receive messages with parenthesis or the plus sign in them, the following all cause multiple threads. Code:1234567890 == 11234567890 +11234567890 (123)4567890 +1(123)4567890 I could go on but you get the point. Manually editing the phone number to match the I think address should be changed to an INT column and all non digits stripped before saving. --Maybe leave the +, I'm not 100% sure how international numbers work. I just use 011-- Then all contact matching should be done right to left ie: try to match 123-4567, then 123 123-4567, etc. To be honest this should extend to the contact database as well. We don't need to save formatting in it, pretty up the number in the GUI not the DB.