Как объединить оператор IN с условием LIKE (или лучший способ получить сопоставимые результаты) - PullRequest
4 голосов
/ 25 января 2010

Мне нужно выбрать строки, где поле начинается с одного из нескольких разных префиксов:

select * from table 
where field like 'ab%' 
  or field like 'cd%' 
  or field like "ef%" 
  or...

Каков наилучший способ сделать это с помощью SQL в Oracle или SQL Server? Я ищу что-то вроде следующих утверждений (которые являются неправильными):

select * from table where field like in ('ab%', 'cd%', 'ef%', ...)

или

select * from table where field like in (select foo from bar)

EDIT: Я хотел бы посмотреть, как это делается с помощью предоставления всех префиксов в одном операторе SELECT или хранения всех префиксов в вспомогательной таблице.

Длина префиксов не фиксирована.

Ответы [ 5 ]

16 голосов
/ 25 января 2010

Объединение таблицы префиксов с фактической таблицей будет работать как в SQL Server, так и в Oracle.

DECLARE @Table TABLE (field VARCHAR(32))
DECLARE @Prefixes TABLE (prefix VARCHAR(32))

INSERT INTO @Table VALUES ('ABC')
INSERT INTO @Table VALUES ('DEF')
INSERT INTO @Table VALUES ('ABDEF')
INSERT INTO @Table VALUES ('DEFAB')
INSERT INTO @Table VALUES ('EFABD')

INSERT INTO @Prefixes VALUES ('AB%')
INSERT INTO @Prefixes VALUES ('DE%')

SELECT  t.*
FROM    @Table t
        INNER JOIN @Prefixes pf ON t.field LIKE pf.prefix 
6 голосов
/ 25 января 2010

вы можете попробовать регулярное выражение

SELECT * from table where REGEXP_LIKE ( field, '^(ab|cd|ef)' );
5 голосов
/ 25 января 2010

Если ваш префикс всегда состоит из двух символов, не могли бы вы просто использовать функцию SUBSTRING (), чтобы получить первые два символа «поля», а затем посмотреть, находится ли он в списке префиксов?

select * from table
where SUBSTRING(field, 1, 2) IN (prefix1, prefix2, prefix3...)

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

1 голос
/ 26 января 2010

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

select * from table   
where field like 'ab%'   
  or field like 'cd%'   
  or field like "ef%"   
  or... 

может быть переписано за кулисами как

select * from table   
 where field like 'ab%'   
union all
select * from table
 where field like 'cd%'   
union all
select * from table
 where field like 'ef%' 

Выполнение трех индексных сканирований вместо полного сканирования.

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

select * from data_table
 where transform(field) in (select pre_transformed_field
                              from my_where_clause_table);
0 голосов
/ 23 апреля 2017

Вы также можете попробовать вот так: здесь tmp - временная таблица, заполненная необходимыми префиксами. Это простой способ, и делает свою работу.

select * from emp join 
(select 'ab%' as Prefix
union
select 'cd%' as Prefix
union
select 'ef%' as Prefix) tmp
on emp.Name like tmp.Prefix
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...