在SQL I中(很遗憾)经常不得不使用“LIKE”条件,因为数据库违反了几乎所有的规范化规则。我现在改变不了。但这与问题无关。

此外,我经常使用诸如WHERE(1,1,2,3,5,8,13,21)中的某些内容之类的条件,以提高SQL语句的可读性和灵活性。

有没有可能在不编写复杂的子选择的情况下将这两者结合起来?

我想要一些像WHERE一样简单的东西('bla%', '%foo%', 'batz%')而不是这样:

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

我在这里与SQl Server和Oracle一起工作,但我感兴趣的是,这是否可能在任何RDBMS中。


当前回答

从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

其他回答

我在这里与SQl Server和Oracle一起工作,但我感兴趣的是,这是否可能在任何RDBMS中。

Teradata支持LIKE ALL/ANY语法:

ALL every string in the list. ANY any string in the list. ┌──────────────────────────────┬────────────────────────────────────┐ │ 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版本支持该语法:

添加合成[NOT]像任何和[NOT]像所有操作符

很多时候,SQL用户希望能够组合like和IN谓词,例如: SELECT * 从客户 WHERE last_name [NOT] LIKE ANY ('A%', 'E%') [ESCAPE '!'] 解决方法是手动将谓词展开为等效谓词 SELECT * 从客户 WHERE last_name LIKE 'A%' 或last_name LIKE 'E%' jOOQ可以开箱即用地支持这样一个合成谓词。


LIKE/ILIKE ANY(数组[]):

SELECT *
FROM t
WHERE c LIKE ANY (ARRAY['A%', '%B']);

SELECT *
FROM t
WHERE c LIKE ANY ('{"Do%", "%at"}');

db < > fiddle演示


雪花也支持LIKE ANY/LIKE ALL匹配:

像任何/所有 允许基于与一个或多个模式比较的字符串进行区分大小写的匹配。 <subject> LIKE ANY (<pattern1> [, <pattern2>…) [ESCAPE <escape_char>]

例子:

SELECT * 
FROM like_example 
WHERE subject LIKE ANY ('%Jo%oe%','T%e')
-- WHERE subject LIKE ALL ('%Jo%oe%','J%e')

从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

在Teradata你可以使用LIKE ANY ('%ABC%','%PQR%','%XYZ%')。下面是一个对我来说产生了相同结果的例子

--===========
--  CHECK ONE
--===========
SELECT *
FROM Random_Table A
WHERE (Lower(A.TRAN_1_DSC) LIKE ('%american%express%centurion%bank%')
OR Lower(A.TRAN_1_DSC) LIKE ('%bofi%federal%bank%')
OR Lower(A.TRAN_1_DSC) LIKE ('%american%express%bank%fsb%'))

;
--===========
--  CHECK TWO
--===========
SELECT *
FROM Random_Table  A
WHERE Lower(A.TRAN_1_DSC) LIKE ANY 
('%american%express%centurion%bank%',
'%bofi%federal%bank%',
'%american%express%bank%fsb%')

如果您想封装上面所示的Inner Join或临时表技术,我建议使用TableValue用户函数。这样可以看得更清楚一点。

在使用定义在:http://www.logiclabz.com/sql-server/split-function-in-sql-server-to-break-comma-separated-strings-into-table.aspx的split函数后

我们可以根据我创建的名为“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.

输出

1   Bass
2   Pike
7   Angler
8   Walleye

如果您希望语句易于阅读,那么可以使用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谓词。这些例子只是为了好玩。