Помогите объединить эти два запроса - PullRequest
0 голосов
/ 03 мая 2010

Мне нужен запрос SQL, который возвращает результаты, совпадающие с ЛИБО из следующих запросов SQL:

Запрос 1:

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)

Запрос 2:

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'))

Вот что я попробовал, но это не работает:

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  INNER JOIN "votes" ON "votes".voteable_id = "annotations".id AND "votes".voteable_type = 'Annotation' WHERE ((votes.vote = 't' and votes.voter_id = 78) OR (annotations.referent IS NOT NULL and annotations.updated_at < '2010-04-05 01:43:52' and (annotations.body = '?' OR annotations.body LIKE '%[?]%') and ((users.id = songs.state_last_updated_by_id and users.needs_edit = 'f') OR songs.state = 'published')))

1 Ответ

1 голос
/ 03 мая 2010

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'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...