Мне нужно реализовать следующий запрос в SQL Server:
select *
from table1
WHERE (CM_PLAN_ID,Individual_ID)
IN
(
Select CM_PLAN_ID, Individual_ID
From CRM_VCM_CURRENT_LEAD_STATUS
Where Lead_Key = :_Lead_Key
)
Но предложение WHERE..IN допускает только 1 столбец. Как я могу сравнить 2 или более столбцов с другим внутренним SELECT?
sql-server
ала
источник
источник
Ответы:
Вы можете создать производную таблицу из подзапроса и присоединить table1 к этой производной таблице:
источник
Вместо этого вы захотите использовать синтаксис WHERE EXISTS.
источник
ВНИМАНИЕ О РЕШЕНИЯХ:
МНОГИЕ СУЩЕСТВУЮЩИЕ РЕШЕНИЯ ДАЮТ НЕПРАВИЛЬНЫЙ ВЫХОД, ЕСЛИ СТРОКИ НЕ УНИКАЛЬНЫ
Если вы являетесь единственным человеком, создающим таблицы, это может быть неактуально, но несколько решений будут давать различное количество выходных строк из рассматриваемого кода, когда одна из таблиц может не содержать уникальных строк.
ПРЕДУПРЕЖДЕНИЕ О ЗАЯВЛЕНИИ ЗАДАЧИ:
В НЕСКОЛЬКИХ КОЛОННАХ НЕ СУЩЕСТВУЕТ, ВНИМАТЕЛЬНО ПУНИТЕ, ЧТО ВЫ ХОТИТЕ
Когда я вижу вход с двумя столбцами, я могу представить, что это означает две вещи:
Сценарий 1 довольно тривиален, просто используйте два оператора IN.
В соответствии с большинством существующих ответов, я настоящим предоставляю обзор упомянутых и дополнительных подходов для Сценария 2 (и краткое суждение):
EXISTS (Безопасный, рекомендуется для SQL Server)
Согласно @mrdenny, EXISTS звучит именно так, как вы ищете, вот его пример:
LEFT SEMI JOIN (Безопасно, рекомендуется для диалектов, которые его поддерживают)
Это очень краткий способ присоединения, но, к сожалению, большинство диалектов SQL, включая SQL-сервер, в настоящее время не поддерживают его.
Несколько операторов IN (безопасно, но остерегайтесь дублирования кода)
Как уже упоминалось @cataclysm, использование двух операторов IN также может помочь, возможно, даже превзойдет другие решения. Тем не менее, вы должны быть очень осторожны с дублированием кода. Если вы когда-нибудь захотите выбрать из другой таблицы или изменить инструкцию where, это увеличит риск того, что вы создадите несоответствия в своей логике.
Основное решение
Решение без дублирования кода (я считаю, что это не работает в обычных запросах SQL Server)
ВНУТРЕННЕЕ СОЕДИНЕНИЕ (технически это можно сделать безопасным, но часто это не делается)
Причина, по которой я не рекомендую использовать внутреннее объединение в качестве фильтра, заключается в том, что на практике люди часто допускают дубликаты в правой таблице, которые вызывают дубликаты в левой таблице. И что еще хуже, они иногда делают конечный результат отличным, в то время как левая таблица может фактически не быть уникальной (или не уникальной в выбранных вами столбцах). Кроме того, это дает вам возможность фактически выбрать столбец, который не существует в левой таблице.
Самые распространенные ошибки:
КОНКАТЕНЦИЯ КОЛОНН С СЕПАРАТОРОМ (не очень безопасно, ужасная производительность)
Функциональная проблема заключается в том, что если вы используете разделитель, который может находиться в столбце, будет сложно убедиться, что результат будет на 100% точным. Техническая проблема заключается в том, что этот метод часто выполняет преобразования типов и полностью игнорирует индексы, что может привести к ужасной производительности. Несмотря на эти проблемы, я должен признать, что иногда я все еще использую его для специальных запросов в небольших наборах данных.
Обратите внимание, что если ваши столбцы являются числовыми, некоторые диалекты SQL потребуют от вас сначала привести их к строкам. Я верю, что SQL-сервер сделает это автоматически.
Подводя итог: как обычно, в SQL есть много способов сделать это, использование безопасных вариантов позволит избежать неожиданностей и сэкономит ваше время и трудности в долгосрочной перспективе.
источник
Примечание.
Oracle игнорирует строки, в которых один или несколько выбранных столбцов имеют значение NULL. В этих случаях вы , вероятно , хотите, чтобы использовать NVL -Funktion для отображения NULL в специальное значение (которое не должно быть в значениях);
источник
where (colA,colB) in (... some list of tuples...)
но я не уверен, что другие базы данных делают то же самое. Мне было бы интересно узнать.Простое предложение EXISTS является самым чистым
Если у вас есть несколько строк в корреляции, то JOIN дает несколько строк в выводе, так что вам нужно отличаться. Что обычно делает EXISTS более эффективным.
Примечание
SELECT *
с JOIN также будет включать столбцы из таблиц ограничения строкисточник
Зачем использовать ГДЕ СУЩЕСТВУЮЩИЕ или ПРОИЗВОДНЫЕ ТАБЛИЦЫ, когда вы можете просто сделать обычное внутреннее соединение:
Если пара (CM_PLAN_ID, Individual_ID) не уникальна в таблице состояний, вам может потребоваться вместо этого SELECT DISTINCT t. *.
источник
1. Использование с
EXISTS
[Среднее время запроса: 1,42 с]2. Использование с двумя строками
IN
Статья [Среднее время запроса: 0,37 с]3. Использование с
INNNER JOIN
шаблоном [Среднее время запроса: 2,9 с]Итак, я выбрал второй вариант.
источник
AND
утверждения, а неOR
утверждения.OR
заявление, вероятно, вызовет дублирование. В моем случае нет ни одной строки, которая бы содержала то же самоеsrc_id
иdest_id
в одной строке. Таким образом, дублирования не произойдет в моем случае.Запрос:
Вышеупомянутый запрос работал для меня в MySQL. см. следующую ссылку ->
https://www.w3resource.com/sql/subqueries/multiplee-row-column-subqueries.php
источник
Если вы хотите для одной таблицы, то используйте следующий запрос
и данные таблицы, как следует
Затем выведите как следует
источник
id in (1,2) and studentName in ('a','b')
совершенно не то же самое, что(id, studentName) in ((1,'a'),(2,'b'))
. Просто подумайте о записи с id = 2 и name = 'a'. Конечно, если ID уникален, то эффект уменьшается, но тогда, если ID уникален, нам вообще не нужно фильтровать имена.Мы можем просто сделать это.
источник
Объединение столбцов вместе в некоторой форме является «хаком», но когда продукт не поддерживает полусоединения для более чем одного столбца, иногда у вас нет выбора.
Пример, где внутреннее / внешнее соединение не будет работать:
Когда запросы не являются тривиальными по своей природе, иногда у вас нет доступа к базовой таблице, установленной для выполнения регулярных внутренних / внешних объединений.
Если вы используете этот «хак», то при объединении полей обязательно добавьте достаточное количество разделителя между ними, чтобы избежать неправильной интерпретации, например
ColA + ":-:" + ColB
источник
Я основал этот путь проще
Надеюсь это поможет :)
источник
CM_PLAN_ID = 45
иIndividual_ID = 3
тогда конкатенация приводит к453
- что неотличимо от случая, когдаCM_PLAN_ID = 4
иIndividual_ID = 53
...45_3
или,45:3
но это все еще не очень хорошее решение, и, конечно, как @mrdenny говорит, что индексы не будут использоваться сейчас, когда преобразование произошло в столбцах.Простым и неправильным способом было бы объединить два столбца, используя + или объединить и сделать один столбец.
Это было бы довольно медленно. Не может быть использовано в программировании, но в случае, если вы просто запрашиваете что-то для проверки, может быть использовано.
источник