В 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 вообще.
В SQL нет комбинации LIKE & IN, тем более в TSQL (SQL Server) или PLSQL (Oracle). Частично это связано с тем, что рекомендуется использовать полнотекстовый поиск (FTS).
Реализации Oracle и SQL Server FTS поддерживают ключевое слово CONTAINS, но синтаксис все же немного отличается:
WHERE CONTAINS(t.something, 'bla OR foo OR batz', 1) > 0
WHERE CONTAINS(t.something, '"bla*" OR "foo*" OR "batz*"')
Ссылка:
вы застряли с
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)
Используйте вместо этого внутреннее соединение:
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
Если вы хотите, чтобы ваш оператор был легко читаемым, вы можете использовать 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. Так что примеры были просто для забавы.
Один из подходов - сохранить условия во временной таблице (или табличной переменной в SQL Server) и присоединиться к ней следующим образом:
SELECT t.SomeField
FROM YourTable t
JOIN #TempTableWithConditions c ON t.something LIKE c.ConditionValue
Я бы посоветовал использовать пользовательскую функцию 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