UNION
самый простой. Если оптимизатор вашего движка не справляется с этим эффективно, я мог бы взглянуть глубже (но все остальное, вероятно, потребовало бы большого количества ЛЕВЫХ СОЕДИНЕНИЙ, поскольку похоже, что вы объединяете два разных использования аннотаций):
SELECT "annotations".*
FROM "annotations"
INNER JOIN "votes"
ON "votes".voteable_id = "annotations".id
AND "votes".voteable_type = 'Annotation'
WHERE (votes.vote = 't' AND votes.voter_id = 78)
UNION
SELECT "annotations".*
FROM "annotations"
INNER JOIN "songs"
ON "songs".id = "annotations".song_id
INNER JOIN "songs" songs_annotations
ON "songs_annotations".id = "annotations".song_id
INNER JOIN "users"
ON "users".id = "songs_annotations".state_last_updated_by_id
WHERE (annotations.referent IS NOT NULL
AND annotations.updated_at < '2010-04-05 01:51:24'
AND (body = '?' OR body LIKE '%[?]%')
AND ((users.id = songs.state_last_updated_by_id and users.needs_edit = 'f' and songs.state != 'work_in_progress') OR (songs.state = 'published'))
По той же причине, по которой ваша попытка ВНУТРЕННЕГО СОЕДИНЕНИЯ не удалась (все критерии соединения должны быть удовлетворены), вам придется изменить почти все на ЛЕВОЕ СОЕДИНЕНИЕ (или ЛЕВОЕ СОЕДИНЕНИЕ для вложенного ВНУТРЕННЕГО СОЕДИНЕНИЯ) - я думаю, что UNION является самым простым. 1005 *
SELECT "annotations".*
FROM "annotations"
LEFT JOIN "votes"
ON "votes".voteable_id = "annotations".id
AND "votes".voteable_type = 'Annotation'
LEFT JOIN "songs"
ON "songs".id = "annotations".song_id
LEFT JOIN "songs" songs_annotations
ON "songs_annotations".id = "annotations".song_id
LEFT JOIN "users"
ON "users".id = "songs_annotations".state_last_updated_by_id
WHERE (votes.vote = 't' AND votes.voter_id = 78)
OR
(annotations.referent IS NOT NULL
AND annotations.updated_at < '2010-04-05 01:51:24'
AND (body = '?' OR body LIKE '%[?]%')
AND ((users.id = songs.state_last_updated_by_id and users.needs_edit = 'f' and songs.state != 'work_in_progress') OR (songs.state = 'published'))