Один запрос для всех записей, не имеющих ключа в таблице соединений, и записей, имеющих соответствующий ключ - PullRequest
0 голосов
/ 02 октября 2009

У меня есть поездка, в которой много резиденций. Мне нужен один запрос, который возвращает все поездки, где не указана информация о месте жительства. И все поездки, которые соответствуют указанному месту жительства.

Я могу получить первое из этого запроса:

SELECT * FROM `trips` WHERE (((NOT EXISTS (SELECT id FROM residencies WHERE trips.id = residencies.trip_id))

Но чтобы получить второе, мне нужно добавить и этот бит:

INNER JOIN `residencies` ON (`trips`.`id` = `residencies`.`trip_id`)

Добавление объединения до предложения WHERE запрашивает результаты с идентификатором места жительства и без идентификатора места жительства. Это, очевидно, ничего не возвращает. Итак, как я могу написать это, чтобы получить полный набор результатов в одном запросе? Хранимые процедуры на этом запрещены.

Я использую Rails, поэтому бонус (но определенно не обязательный), если ответ зависит от Rails. И огромный бонус, если кто-то может показать, как это можно сделать с помощью плагина searchlogic.

В настоящее время у меня есть первое требование в качестве именованной области:

Trip.named_scope :residencies_empty, :conditions => ['NOT EXISTS (SELECT id FROM residencies WHERE trips.id = residencies.trip_id)']

Второе требование доступно через searchlogic:

Trip.residences_id_equals(id)

Идеальным решением была бы поисковая логика, которая выглядит следующим образом:

Trip.residencies_null_or_residencies_id_equals(id)

Ответы [ 3 ]

0 голосов
/ 02 октября 2009

Вы пытались использовать UNION для объединения результатов двух запросов?

0 голосов
/ 02 октября 2009

Я предлагаю использовать другой «EXIST» для поездок с определенным местом жительства:

SELECT * FROM `trips` WHERE 
  (NOT EXISTS (SELECT id FROM residencies WHERE trips.id = residencies.trip_id))
  OR
  (EXISTS (SELECT id FROM residencies WHERE trips.id = residencies.trip_id 
           AND other_criteria_for_specific_residency)
  )

Это кажется наиболее читаемым решением, но если производительность важна, вы должны проверить EXPAIN, чтобы увидеть, как это оптимизируется (как в большинстве сложных запросов в MySql).

0 голосов
/ 02 октября 2009

TRY:

SELECT * FROM `trips`
    LEFT JOIN  residencies ON trips.id = residencies.trip_id

Вы получите данные во всех столбцах из trips, но данные будут заполняться только в столбцах из резиденций, где существовала строка, если не было строки резиденций, эти столбцы будут нулевыми.

...