Существует ли комбинация “ПОДОБНЫХ” и “В” в SQL?

В SQL I (печально) часто должны использовать"LIKE"условия из-за баз данных, которые нарушают почти каждое правило нормализации. Я не могу изменить это прямо сейчас. Но это не важно вопросу.

Далее, я часто использую условия как WHERE something in (1,1,2,3,5,8,13,21) для лучшей удобочитаемости и гибкости моих SQL-операторов.

Там какой-либо возможный путь состоит в том, чтобы объединиться, эти две вещи, не пишущий сложный подвыбирает?

Я хочу что-то столь же легкое как WHERE something LIKE ('bla%', '%foo%', 'batz%') вместо этого:

WHERE something LIKE 'bla%'
OR something LIKE '%foo%'
OR something LIKE 'batz%'

Я работаю с SQL-сервером и Oracle здесь, но мне интересно, если это возможно в каком-либо RDBMS вообще.

322
задан rogerdpack 26 September 2018 в 07:29
поделиться

6 ответов

В SQL нет комбинации LIKE & IN, тем более в TSQL (SQL Server) или PLSQL (Oracle). Частично это связано с тем, что рекомендуется использовать полнотекстовый поиск (FTS).

Реализации Oracle и SQL Server FTS поддерживают ключевое слово CONTAINS, но синтаксис все же немного отличается:

Oracle:

WHERE CONTAINS(t.something, 'bla OR foo OR batz', 1) > 0

SQL Server:

WHERE CONTAINS(t.something, '"bla*" OR "foo*" OR "batz*"')

Ссылка:

185
ответ дан 23 November 2019 в 00:56
поделиться

вы застряли с

WHERE something LIKE 'bla%'
OR something LIKE '%foo%'
OR something LIKE 'batz%'

если вы не заполните временную таблицу (включите дикие карты в данные) и не соедините их следующим образом:

FROM YourTable                y
    INNER JOIN YourTempTable  t On y.something LIKE t.something

попробуйте (используя синтаксис SQL Server):

declare @x table (x varchar(10))
declare @y table (y varchar(10))

insert @x values ('abcdefg')
insert @x values ('abc')
insert @x values ('mnop')

insert @y values ('%abc%')
insert @y values ('%b%')

select distinct *
FROM @x x
WHERE x.x LIKE '%abc%' 
   or x.x LIKE '%b%'


select distinct x.*  
FROM @x             x
    INNER JOIN  @y  y On x.x LIKE y.y

OUTPUT:

x
----------
abcdefg
abc

(2 row(s) affected)

x
----------
abc
abcdefg

(2 row(s) affected)
48
ответ дан 23 November 2019 в 00:56
поделиться

Используйте вместо этого внутреннее соединение:

SELECT ...
FROM SomeTable
JOIN
(SELECT 'bla%' AS Pattern 
UNION ALL SELECT '%foo%'
UNION ALL SELECT 'batz%'
UNION ALL SELECT 'abc'
) AS Patterns
ON SomeTable.SomeColumn LIKE Patterns.Pattern
7
ответ дан 23 November 2019 в 00:56
поделиться

Если вы хотите, чтобы ваш оператор был легко читаемым, вы можете использовать REGEXP_LIKE (доступно начиная с Oracle версии 10).

Пример таблицы:

SQL> create table mytable (something)
  2  as
  3  select 'blabla' from dual union all
  4  select 'notbla' from dual union all
  5  select 'ofooof' from dual union all
  6  select 'ofofof' from dual union all
  7  select 'batzzz' from dual
  8  /

Table created.

Исходный синтаксис:

SQL> select something
  2    from mytable
  3   where something like 'bla%'
  4      or something like '%foo%'
  5      or something like 'batz%'
  6  /

SOMETH
------
blabla
ofooof
batzzz

3 rows selected.

И простой на вид запрос с REGEXP_LIKE

SQL> select something
  2    from mytable
  3   where regexp_like (something,'^bla|foo|^batz')
  4  /

SOMETH
------
blabla
ofooof
batzzz

3 rows selected.

НО ...

Я бы сам не рекомендовал его из-за не очень хорошей производительности. Я бы придерживался нескольких предикатов LIKE. Так что примеры были просто для забавы.

57
ответ дан 23 November 2019 в 00:56
поделиться

Один из подходов - сохранить условия во временной таблице (или табличной переменной в SQL Server) и присоединиться к ней следующим образом:

SELECT t.SomeField
FROM YourTable t
   JOIN #TempTableWithConditions c ON t.something LIKE c.ConditionValue
7
ответ дан 23 November 2019 в 00:56
поделиться

Я бы посоветовал использовать пользовательскую функцию TableValue, если вы хотите инкапсулировать методы внутреннего соединения или временных таблиц, показанные выше. Это позволило бы его читать немного яснее.

После использования функции разделения, определенной по адресу: http://www.logiclabz.com/sql-server/split-function-in-sql-server-to-break-comma-separated-strings-into- table.aspx

мы можем написать следующее на основе созданной мной таблицы под названием «Fish» (int id, varchar (50) Name)

SELECT Fish.* from Fish 
    JOIN dbo.Split('%ass,%e%',',') as Splits 
    on Name like Splits.items  //items is the name of the output column from the split function.

Outputs

1   Bass
2   Pike
7   Angler
8   Walleye
10
ответ дан 23 November 2019 в 00:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: