СОЮЗЫ и СОЕДИНЕНИЯ делают совершенно разные вещи.
UNION добавляют записи в конец запроса, JOINs добавляют поля в конец записи.
Если ваш запрос UNION работает, то я бы порекомендовал вам придерживаться его. Если вы действительно хотите сделать это с JOIN, то вы можете сделать следующее и соответственно изменить свой рабочий процесс.
SELECT message_id, message_title, user.name, corp.name
FROM group_messages
LEFT JOIN users ON
users.user_id = group_messages.user_id
AND group_messages.usertype = "1"
LEFT JOIN corp ON
corp.user_id = group_messages.user_id
AND group_messages.usertype = "0"
;
Что это будет делать, так это возвращать записи с полями для пользователя И поля для корп. Когда usertype равен 1, пользовательские поля будут заполнены, а поля corp будут нулевыми. Когда usertype равен 0, поля corp будут заполнены, а поля пользователя будут нулевыми. Вам нужно будет написать логику приложения, чтобы прочитать возвращенный тип пользователя и определить, какой набор полей читать.
Честно говоря, если вы сделаете что-то подобное, вам будет гораздо лучше просто сделать два отдельных запроса.
Если вы не хотите, чтобы данные для каждого типа находились в отдельных полях, вы не должны использовать JOIN. Если вы хотите, чтобы данные каждого типа возвращались в одно и то же поле, вам нужен UNION, который у вас уже есть.