Как я могу написать запрос, который исключает определенные результаты, но включает результаты, в которых отсутствует связь, используемая для исключения? - PullRequest
1 голос
/ 13 мая 2009

У меня есть поисковая форма, используемая для запроса условий предоставления услуг, которую я назову «положения». Положения могут иметь определенные квалификационные требования в отношении "имеет" и принадлежат многим отношениям, но они могут также не иметь никаких требований вообще. Моя проблема в том, что, когда я исключаю определенные положения на основе конкретного требования, те положения, которые вообще не имеют требований, также исключаются.

Структура таблицы:

provisions
* id
* title

requirements
* id
* title

provisions_requirements
* provision_id
* requirement_id

Предположим, что требование равно:

Canadian Citizenship (id 4)

Это будет представлено в форме, такой как: «Исключить услуги, для которых требуется: канадское гражданство».

Таким образом, исключительная часть запроса будет:

requirements.id NOT IN (4)

Однако тогда я получаю только положения, в которых есть хотя бы одно требование, потому что те положения, в которых нет требований, не включаются в соединение.

Фактический запрос выглядит так:

SELECT DISTINCT `provisions`.id 
FROM `provisions` 
LEFT OUTER JOIN `provisions_requirements` 
  ON `provisions_requirements`.provision_id = `provisions`.id 
LEFT OUTER JOIN `requirements` 
  ON `requirements`.id = `provisions_requirements`.requirement_id 
WHERE (requirements.id NOT IN ('1')) 
LIMIT 0, 10

Ответы [ 4 ]

3 голосов
/ 13 мая 2009

Итак, вам нужны все услуги , за исключением , которые требуют канадского гражданства (req_id 4)?

Попробуйте это: он пытается сопоставить с requirement_id из 4, но условие в предложении WHERE делает так, чтобы только условия, которые не нашли такого соответствия, удовлетворяли условию.

SELECT p.id
FROM provisions p LEFT OUTER JOIN provisions_requirements r
 ON (p.id = r.provision_id AND r.requirement_id IN (4))
WHERE r.requirement_id IS NULL
LIMIT 0, 10;

Нет DISTINCT необходимо. Присоединение к таблице requirements не требуется.

1 голос
/ 13 мая 2009
SELECT
     P.id
FROM
     Provisions P
WHERE
     NOT EXISTS
     (
          SELECT
               *
          FROM
               Provision_Requirements PR
          WHERE
               PR.provision_id = P.id AND
               PR.requirement_id = 4
     )
0 голосов
/ 13 мая 2009

ваш запрос там на 99%, просто включите тест на NULL

SELECT DISTINCT `provisions`.id 
FROM `provisions` 
LEFT OUTER JOIN `provisions_requirements` 
  ON `provisions_requirements`.provision_id = `provisions`.id 
LEFT OUTER JOIN `requirements` 
  ON `requirements`.id = `provisions_requirements`.requirement_id 
WHERE (requirements.id NOT IN ('1')) 
or requirements.id is NULL -- test for null
LIMIT 0, 10

это будет включать те строки, в которых нет записи в таблице Provision_requirements

0 голосов
/ 13 мая 2009

попробуйте это:

SELECT DISTINCT `provisions`.id 
FROM `provisions` 
LEFT OUTER JOIN `provisions_requirements` ON `provisions_requirements`.provision_id = `provisions`.id 
LEFT OUTER JOIN `requirements` ON `requirements`.id = `provisions_requirements`.requirement_id and (requirements.id NOT IN ('1'))
LIMIT 0, 10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...