Альтернативные методы SQL для поиска нескольких элементов известных идентификаторов?

Есть ли лучшее решение проблемы поиска нескольких известных идентификаторов в таблице:

SELECT * FROM some_table WHERE id='1001' OR id='2002' OR id='3003' OR ...

У меня может быть несколько сотен известных предметов. Идеи?

Ответ 1

SELECT * FROM some_table WHERE ID IN ('1001', '1002', '1003')

и если ваши известные идентификаторы поступают из другой таблицы

SELECT * FROM some_table WHERE ID IN (
    SELECT KnownID FROM some_other_table WHERE someCondition 
)

Ответ 2

Первая (наивная) опция:

SELECT * FROM some_table WHERE id IN ('1001', '2002', '3003' ... )

Однако мы должны быть в состоянии сделать лучше. IN очень плохо, когда у вас много предметов, и вы упомянули сотни этих идентификаторов. Что их создает? Откуда они? Вы можете написать запрос, который возвращает этот список? Если да:

SELECT *
FROM some_table 
INNER JOIN ( your query here) filter ON some_table.id=filter.id

Ответ 4

OR SQL, как известно, медленны в SQL.

Ваш вопрос не соответствует специфике, но в зависимости от ваших требований и ограничений я бы построил справочную таблицу с вашими идентификаторами и использовал предикат EXISTS:

select t.id from some_table t 
where EXISTS (select * from lookup_table l where t.id = l.id)

Ответ 5

Для фиксированного набора идентификаторов вы можете:

SELECT * FROM some_table WHERE id IN (1001, 2002, 3003);

Для набора, который изменяется каждый раз, вам может понадобиться создать таблицу для их хранения, а затем запросить:

SELECT * FROM some_table WHERE id IN 
  (SELECT id FROM selected_ids WHERE key=123);

Другой подход - использовать коллекции - синтаксис для этого будет зависеть от вашей СУБД.

Наконец, всегда существует такой "клочковый" подход:

SELECT * FROM some_table WHERE '|1001|2002|3003|' LIKE '%|' || id || '|%';

Ответ 6

В Oracle я всегда ставил id в TEMPORARY TABLE для выполнения массивных операций SELECT и DML:

CREATE GLOBAL TEMPORARY TABLE t_temp (id INT)


SELECT  *
FROM    mytable
WHERE   mytable.id IN
        (
        SELECT  id
        FROM    t_temp
        )

Вы можете заполнить временную таблицу в одном клиентском сервере с помощью Oracle типов коллекций.

Ответ 7

У нас есть аналогичная проблема в приложении, написанном для MS SQL Server 7. Хотя мне не нравится используемое решение, мы не знаем ничего лучшего...

"Лучшие" решения существуют в 2008 году, насколько я знаю, но у нас есть клиенты Zero, которые используют это:)


Мы создали функцию, зависящую от таблицы, которая использует строку идентификаторов с разделителями-запятыми и возвращает таблицу идентификаторов. SQL тогда читается достаточно хорошо, и ни один из них не является динамическим, но все еще есть раздражающие двойные накладные расходы:
1. Клиент объединяет идентификаторы в строку. 2. SQL Server анализирует строку для создания таблицы идентификаторов

Существует множество способов превратить "1,2,3,4,5" в таблицу идентификаторов, но хранимая процедура, использующая эту функцию, выглядит как...

CREATE PROCEDURE my_road_to_hell @IDs AS VARCHAR(8000)
AS
BEGIN

   SELECT
      *
   FROM
      myTable
   INNER JOIN
      dbo.fn_split_list(@IDs) AS [IDs]
         ON [IDs].id = myTable.id

END

Ответ 8

Самый быстрый - добавить идентификаторы в другую таблицу и ПРИСОЕДИНЯЙТЕСЬ

SELECT some_table.* 
FROM some_table INNER JOIN some_other_table ON some_table.id = some_other_table.id

где some_other_table будет иметь только одно поле (ids), и все значения будут уникальными