Ограничение условия WHERE col IN (...)

Я использую следующий код:

SELECT * FROM table
WHERE Col IN (123,123,222,....)

Однако, если я поставлю более ~3000 номеров в IN предложение, SQL выдает ошибку.

Кто-нибудь знает, есть ли ограничение по размеру или что-то подобное?!!

9 ответов

Решение

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

SQL Server имеет очень большое ограничение:

http://msdn.microsoft.com/en-us/library/ms143432.aspx

У ORACLE очень легко достичь предела с другой стороны.

Итак, для больших предложений IN лучше создать временную таблицу, вставить значения и выполнить JOIN. Это также работает быстрее.

Существует ограничение, но вы можете разделить ваши значения на отдельные блоки in()

Select * 
From table 
Where Col IN (123,123,222,....)
or Col IN (456,878,888,....)

Параметризовать запрос и передать идентификаторы с помощью параметра Table Valued.

Например, определите следующий тип:

CREATE TYPE IdTable AS TABLE (Id INT NOT NULL PRIMARY KEY)

Наряду со следующей хранимой процедурой:

CREATE PROCEDURE sp__Procedure_Name
    @OrderIDs IdTable READONLY,
AS

    SELECT *
    FROM table
    WHERE Col IN (SELECT Id FROM @OrderIDs)

Почему бы не сделать, где в суб-выберите...

Предварительный запрос во временную таблицу или что-то...

CREATE TABLE SomeTempTable AS
    SELECT YourColumn
    FROM SomeTable
    WHERE UserPickedMultipleRecordsFromSomeListOrSomething

затем...

SELECT * FROM OtherTable
WHERE YourColumn IN ( SELECT YourColumn FROM SomeTempTable )

В зависимости от вашей версии, используйте параметр с табличным значением в 2008 году или какой-либо подход, описанный здесь:

Массивы и списки в SQL Server 2005

Для MS SQL 2016, передавая ints в in, похоже, что он может обрабатывать около 38000 записей.

select * from user where userId in (1,2,3,etc)

Я решил это, просто используя диапазоны

      WHERE Col >= 123 AND Col <= 10000

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

Конечно, это не универсальное решение, но оно может работать в ситуации, когда требуется большинство значений в пределах min и max.

Вы не указали движок базы данных - это вопрос; в Oracle можно использовать следующие кортежи:

ВЫБРАТЬ * ИЗ таблицы ГДЕ (Col, 1) IN ((123,1),(123,1),(222,1),....)

Этот безобразный хак работает только в Oracle SQL, см. https://asktom.oracle.com/pls/asktom/asktom.search?tag=limit-and-conversion-very-long-in-list-where-x-in

Однако гораздо лучшим вариантом является использование хранимых процедур и передача значений в виде массива.

Вы можете использовать следующие кортежи: SELECT * FROM table WHERE (Col, 1) IN ((123,1),(123,1),(222,1),....)

Нет ограничений по количеству таких. Он сравнивает пары.

Другие вопросы по тегам