Как реализовать КАЖДЫЕ и НЕТ операции для объединенной таблицы «список» - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть две таблицы Person и _Person_Name, которые содержат столбец Name и столбец Owner с Person.Id в качестве внешнего ключа.Я ищу две операции поиска, которые я бы назвал КАЖДЫЙ и НЕТ .

1.) Каждый

Следующее возвращает только идентификаторы лиц, для которых все соответствующие имена соответствуют запросу LIKE '%n%':

SELECT Person.Id as Result FROM Person
INNER JOIN _Person_Name AS __T1 ON Person.Id = __T1.Owner 
WHERE __T1.Name LIKE '%n%'
GROUP BY Result
HAVING Count(Result)=(Select Count(*) FROM _Person_Name 
  WHERE Person.Id=_Person_Name.Owner)

Но проблема в том, что мне также приходится иметь делос другими запросами, для которых достаточно только одного совпадения, и условие HAVING применяется ко всем терминам в предложении WHERE.

Есть ли способ получить тот же эффект, что и в предложении HAVING в приведенном выше запросе, нокак-то выразить это в предложении WHERE, чтобы к нему можно было добавить другие обычные условия?

Пример:

SELECT Person.Id as Result FROM Person 
INNER JOIN _Person_Name AS __T1 ON Person.Id = __T1.Owner
WHERE (EVERY __T1.Name LIKE '%n%') 
OR (__T1.Name LIKE 'John')

Второй дизъюнкт должен вести себя обычным образом без каких-либо ограничений.Сейчас я ищу способ выразить КАЖДЫЙ , как в приведенном выше предложении HAVING .Запрос должен возвращать __T1.Owner (= Person.Id) всякий раз, когда имеет место одно поле с совпадающим владельцем, имеет поле имени __T1.Name LIKE 'John' или все __T1.Name поля с совпадающимвладелец содержит 'n'.

Если это невозможно выразить в предложении WHERE, как это можно выразить?

2.) Нет

Операция поиска NO похожа на EVERY , но базовое условие отменено, т. Е. Я ищу людей, для которых ни одна из связанных с ними частей имени не соответствует запросу,Я полагаю, что я могу получить это легко, если у меня есть решение для КАЖДЫЙ .

РЕДАКТИРОВАТЬ: Ответ Давида Лачко является правильным.Если он еще не отредактировал свой ответ, требуется небольшое изменение.Вот решение для НЕТ, основанное на его ответе:

SELECT DISTINCT Person.Id as Result FROM Person 
INNER JOIN _Person_Name AS __T1 ON Person.Id = __T1.Owner
WHERE
    NOT EXISTS (
        SELECT 1 FROM _Person_Name AS __T2
        WHERE __T2.Name LIKE '%n%' AND Person.Id=__T2.Owner
        )

1 Ответ

0 голосов
/ 16 ноября 2018

Позвольте мне начать с идеи для НЕТ: вы можете проверить, не существует ли строка, если вы посмотрите по условию LIKE '% n%'. Вы можете сделать это в предложении WHERE с помощью подзапроса EXISTS:

WHERE
    NOT EXISTS (
        SELECT 1 FROM _Person_Name AS __T2 WHERE Person.Id = __T2.Owner
        and __T2.Name LIKE '%n%'
        )
OR (__T1.Name LIKE 'John')

NOT EXISTS проверяет, нет ли совпадений.

Исходя из этого, реализация для КАЖДОГО заключается в том, чтобы проверить, истинно ли отрицание вашего условия для ни одной строки, поэтому вы ищите NOT LIKE '% n%':

WHERE
    NOT EXISTS (
        SELECT 1 FROM _Person_Name AS __T2 WHERE Person.Id = __T2.Owner
        and __T2.Name NOT LIKE '%n%'
        )
OR (__T1.Name LIKE 'John')

На этот раз NOT EXISTS удостоверится, что не найдено ни одной строки, которая НЕ соответствует вашим критериям - следовательно, КАЖДЫЙ ряд соответствует этому.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...