A: 

By using the wildcard "%", its finding anything that matches, much like that of doing a DOS search by file names... CM1 is same wildcard as CM16, CM17, CM192, CM11189. Your join should be on exact same postcode, and only use your wildcard on the result criteria you want to restrict down to...

SELECT 
      user.postcode, 
      postcode.postcode 
   FROM user 
      INNER JOIN postcode ON user.postcode = postcode.postcode
   WHERE 
      user.postcode LIKE  "CM%"
   LIMIT 0 , 30 
DRapp
Unfortunately I only have data for the first half so this wouldn't work. I tried GROUP BY user.postcode but that always matched the first hit. Can I order a table before the JOIN?
Simon
+1  A: 

try this out

SELECT user.postcode, max(postcode.postcode) as postcode
FROM user
INNER JOIN postcode ON user.postcode LIKE CONCAT( postcode.postcode,  "%" ) 
WHERE user.postcode LIKE  "CM%"
GROUP BY user.postcode
LIMIT 0 , 30
ovais.tariq
Great. Just what I was after thanks!
Simon
+1  A: 

Try matching against the first half of the postcode and a space, eg. LIKE CONCAT(postcode, ' %').

Or this might help you to reformat the post codes:

SELECT
    CONCAT( substr(p, 1, length(p)-3), ' ', substr(p, -3) )
FROM (SELECT 'CM159ES' p) a;
ar
This will not work as the postcodes are badly formated. Thanks.
Simon
Try my query above to reformat the post codes (it assumes, I believe safely, that the latter part of the post code is always 3 characters).
ar
Good idea. Correct I believe the last part is always 3 characters...
Simon