SELECT DISTINCT ON( LOWER(COALESCE(SUBSTRING(value from '<(.*)>'), value))) COALESCE(named.count, 1), LOWER(COALESCE(named.name, LOWER(COALESCE(SUBSTRING(value from '<(.*)>'), value)))) AS id, unnamed.name AS name FROM header unnamed LEFT OUTER JOIN ( SELECT DISTINCT ON (LOWER(COALESCE(SUBSTRING(value from '<(.*)>'), value))) COUNT(value) AS count, SUBSTRING(value from '(.*)<') AS name, LOWER(COALESCE(SUBSTRING(value from '<(.*)>'), value)) AS id FROM header WHERE name != '' GROUP BY LOWER(COALESCE(SUBSTRING(value from '<(.*)>'), value)), SUBSTRING(value from '(.*)<') ORDER BY id, count DESC, name ) named ON named.id = LOWER(COALESCE(SUBSTRING(unnamed.value from '<(.*)>'), unnamed.value)) ;