sel*_*oup 322 sql t-sql sql-server oracle plsql
在SQL中(遗憾的是)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%'
Run Code Online (Sandbox Code Playgroud)
我在这里使用SQl Server和Oracle,但我很感兴趣,如果在任何RDBMS中都可以这样做.
OMG*_*ies 185
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
Run Code Online (Sandbox Code Playgroud)
WHERE CONTAINS(t.something, '"bla*" OR "foo*" OR "batz*"')
Run Code Online (Sandbox Code Playgroud)
参考:
Rob*_*ijk 57
如果您想使您的语句易于阅读,那么您可以使用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.
Run Code Online (Sandbox Code Playgroud)
原始语法:
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.
Run Code Online (Sandbox Code Playgroud)
使用REGEXP_LIKE进行简单查看
SQL> select something
2 from mytable
3 where regexp_like (something,'^bla|foo|^batz')
4 /
SOMETH
------
blabla
ofooof
batzzz
3 rows selected.
Run Code Online (Sandbox Code Playgroud)
但......
由于性能不佳,我不会自己推荐它.我坚持使用几个LIKE谓词.所以这些例子只是为了好玩.
KM.*_*KM. 48
你被困在了
WHERE something LIKE 'bla%'
OR something LIKE '%foo%'
OR something LIKE 'batz%'
Run Code Online (Sandbox Code Playgroud)
除非你填充临时表(包括带有数据的通配符)并加入如下:
FROM YourTable y
INNER JOIN YourTempTable t On y.something LIKE t.something
Run Code Online (Sandbox Code Playgroud)
尝试一下(使用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
Run Code Online (Sandbox Code Playgroud)
OUTPUT:
x
----------
abcdefg
abc
(2 row(s) affected)
x
----------
abc
abcdefg
(2 row(s) affected)
Run Code Online (Sandbox Code Playgroud)
Ben*_*oit 19
随着PostgreSQL的存在ANY或ALL形式:
WHERE col LIKE ANY( subselect )
Run Code Online (Sandbox Code Playgroud)
要么
WHERE col LIKE ALL( subselect )
Run Code Online (Sandbox Code Playgroud)
subselect只返回一列数据.
mik*_*mik 12
另一个解决方案应该适用于任何RDBMS:
WHERE EXISTS (SELECT 1
FROM (SELECT 'bla%' pattern FROM dual UNION ALL
SELECT '%foo%' FROM dual UNION ALL
SELECT 'batz%' FROM dual)
WHERE something LIKE pattern)
Run Code Online (Sandbox Code Playgroud)
Fam*_*erd 10
如果您想要封装上面显示的内部连接或临时表技术,我建议使用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.
Run Code Online (Sandbox Code Playgroud)
输出
1 Bass 2 Pike 7 Angler 8 Walleye
一种方法是将条件存储在临时表(或SQL Server中的表变量)中并加入到这样的:
SELECT t.SomeField
FROM YourTable t
JOIN #TempTableWithConditions c ON t.something LIKE c.ConditionValue
Run Code Online (Sandbox Code Playgroud)
改为使用内连接:
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
Run Code Online (Sandbox Code Playgroud)
从 2016 年开始,SQL Server 包含一个STRING_SPLIT 功能. 我正在使用 SQL Server v17.4,它对我有用:
DECLARE @dashboard nvarchar(50)
SET @dashboard = 'P1%,P7%'
SELECT * from Project p
JOIN STRING_SPLIT(@dashboard, ',') AS sp ON p.ProjectNumber LIKE sp.value
Run Code Online (Sandbox Code Playgroud)
你甚至可以尝试这个
功能
CREATE FUNCTION [dbo].[fn_Split](@text varchar(8000), @delimiter varchar(20))
RETURNS @Strings TABLE
(
position int IDENTITY PRIMARY KEY,
value varchar(8000)
)
AS
BEGIN
DECLARE @index int
SET @index = -1
WHILE (LEN(@text) > 0)
BEGIN
SET @index = CHARINDEX(@delimiter , @text)
IF (@index = 0) AND (LEN(@text) > 0)
BEGIN
INSERT INTO @Strings VALUES (@text)
BREAK
END
IF (@index > 1)
BEGIN
INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))
SET @text = RIGHT(@text, (LEN(@text) - @index))
END
ELSE
SET @text = RIGHT(@text, (LEN(@text) - @index))
END
RETURN
END
Run Code Online (Sandbox Code Playgroud)
询问
select * from my_table inner join (select value from fn_split('ABC,MOP',','))
as split_table on my_table.column_name like '%'+split_table.value+'%';
Run Code Online (Sandbox Code Playgroud)
小智 5
我有一个简单的解决方案,至少在postgresql中有效,使用like any后跟正则表达式列表。这是一个示例,查看如何识别列表中的一些抗生素:
select *
from database.table
where lower(drug_name) like any ('{%cillin%,%cyclin%,%xacin%,%mycine%,%cephal%}')
Run Code Online (Sandbox Code Playgroud)
我在这里使用SQl Server和Oracle,但是我很感兴趣是否可以在任何RDBMS中实现。
Teradata支持LIKE ALL/ANY语法:
列表中的所有字符串。
ANY 列表中的任何字符串。Run Code Online (Sandbox Code Playgroud)????????????????????????????????????????????????????????????????????? ? THIS expression … ? IS equivalent to this expression … ? ????????????????????????????????????????????????????????????????????? ? x LIKE ALL ('A%','%B','%C%') ? x LIKE 'A%' ? ? ? AND x LIKE '%B' ? ? ? AND x LIKE '%C%' ? ? ? ? ? x LIKE ANY ('A%','%B','%C%') ? x LIKE 'A%' ? ? ? OR x LIKE '%B' ? ? ? OR x LIKE '%C%' ? ?????????????????????????????????????????????????????????????????????
jOOQ版本3.12.0支持以下语法:
很多时候,SQL用户希望能够结合使用LIKE和IN谓词,例如:
Run Code Online (Sandbox Code Playgroud)SELECT * FROM customer WHERE last_name [ NOT ] LIKE ANY ('A%', 'E%') [ ESCAPE '!' ]解决方法是将谓词手动扩展为等效谓词
Run Code Online (Sandbox Code Playgroud)SELECT * FROM customer WHERE last_name LIKE 'A%' OR last_name LIKE 'E%'jOOQ可以立即支持这种综合谓词。
也许你认为这样的组合:
SELECT *
FROM table t INNER JOIN
(
SELECT * FROM (VALUES('bla'),('foo'),('batz')) AS list(col)
) l ON t.column LIKE '%'+l.Col+'%'
Run Code Online (Sandbox Code Playgroud)
如果您已经为目标表定义了全文索引,那么您可以使用以下替代方案:
SELECT *
FROM table t
WHERE CONTAINS(t.column, '"bla*" OR "foo*" OR "batz*"')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
425243 次 |
| 最近记录: |