在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中。


当前回答

PostgreSQL有ANY或ALL表单:

WHERE col LIKE ANY( subselect )

or

WHERE col LIKE ALL( subselect )

其中子选择只返回一列数据。

其他回答

如果您想封装上面所示的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

我可能有一个解决方案,虽然它将只工作在SQL Server 2008据我所知。我发现你可以使用https://stackoverflow.com/a/7285095/894974中描述的行构造函数使用like子句来连接一个“虚构的”表。 听起来比实际复杂多了,看:

SELECT [name]
  ,[userID]
  ,[name]
  ,[town]
  ,[email]
FROM usr
join (values ('hotmail'),('gmail'),('live')) as myTable(myColumn) on email like '%'+myTable.myColumn+'%' 

这将导致所有用户的电子邮件地址与列表中提供的相同。 希望对大家有用。这个问题困扰了我一段时间。

在SQL SERVER中使用游标并执行每一个值:

表样例:

 create table Gastos_ConciliacionExcluida(IdRegistro int identity(1,1), MascaraTexto nvarchar(50), Activa bit default 1, Primary key (IDRegistro))


insert into Gastos_ConciliacionExcluida(MascaraTexto) Values ('%Reembolso%')



alter procedure SP_Gastos_ConciliacionExcluidaProcesar
as

declare cur cursor for select MascaraTexto From Gastos_ConciliacionExcluida where Activa=1
declare @Txt nvarchar(50)

open cur

fetch next from cur into @Txt
while @@Fetch_Status = 0
begin
    update Gastos_BancoRegistro set PresumibleNoConciliable = 1 
    where   Concepto like @txt
    fetch next from cur into @Txt
end 
close cur
deallocate cur

另一个解决方案,应该适用于任何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)

内部选择可以用另一个模式源替换,比如表(或视图),如下所示:

WHERE EXISTS (SELECT 1
                FROM table_of_patterns t
               WHERE something LIKE t.pattern)

Table_of_patterns应该至少包含一个列模式,可以像这样填充:

INSERT INTO table_of_patterns(pattern) VALUES ('bla%');
INSERT INTO table_of_patterns(pattern) VALUES ('%foo%');
INSERT INTO table_of_patterns(pattern) VALUES ('batz%');

在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%')