MySQL: Могу ли я создать предложение IN, объединяющее оба результата из оператора SELECT и жестко закодированный список? - PullRequest
0 голосов
/ 11 февраля 2019

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

SELECT p.* FROM Person p 
WHERE p.name IN ('jim', 'sally') OR p.name IN (SELECT name FROM goodNames)

Теперь этот запрос работает нормально, но это критически важный для производительности запрос, поэтому я хотел бы иметь возможность объединить два INпредложения типа:

SELECT p.* FROM Person p 
WHERE p.name IN ('jim', 'sally', (SELECT name FROM goodNames))

(это дает ошибку: подзапрос возвращает более 1 строки)

Примечание: 'jim' и 'sally' могут быть или не быть в goodNames, иМне бы хотелось получить результаты как goodNames, так и результаты из предоставленного списка

Есть ли способ сделать это в MySQL?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Вы можете получить это в одном запросе через левое соединение Person и таблицы gooNames:

SELECT p.* FROM Person p LEFT JOIN goodNames g ON p.name = g.name WHERE p.name IN ('jim', 'sally') OR g.name IS NOT NULL
0 голосов
/ 11 февраля 2019

Когда производительность индекса ИЛИ, которая, как я полагаю, будет для вас важна, может привести к тому, что вы будете использовать менее чем идеальную тактику преобразования их в UNION, например:

SELECT p.* FROM Person p 
WHERE p.name IN ('jim', 'sally')
UNION
SELECT p.* FROM Person p 
WHERE p.name IN (SELECT name FROM goodNames)

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

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


некоторые другие неуклюжие альтернативы ...

WHERE p.name IN (
   SELECT name FROM goodNames 
   UNION SELECT 'jim' 
   UNION SELECT 'sally'
)

или

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

WHERE p.name IN (
   SELECT name FROM goodNames 
   UNION SELECT name FROM staticNames
)

О, ха-ха, еще один (вы вернулись к ИЛИ с этим, но это альтернатива, которая может как-то лучше использовать индексы или нет):

SELECT p.* 
FROM Person p 
LEFT JOIN goodNames AS g ON p.name = g.name
WHERE g.name IS NOT NULL OR p.name IN ('jim', 'sally')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...