在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中。
您可以以牺牲性能为代价,为大量元素动态地执行此操作,但这是可行的。
DECLARE @val nvarchar(256),
@list nvarchar(max) = 'one,two,three,ten,five';
CREATE table #table (FIRST_NAME nvarchar(512), LAST_NAME nvarchar(512));
CREATE table #student (FIRST_NAME nvarchar(512), LAST_NAME nvarchar(512), EMAIL
nvarchar(512));
INSERT INTO #student (FIRST_NAME, LAST_NAME, EMAIL)
SELECT 'TEST', ' redOne' ,'test.redOne@toto.com' UNION ALL
SELECT 'student', ' student' ,'student@toto.com' UNION ALL
SELECT 'student', ' two' ,'student.two@toto.com' UNION ALL
SELECT 'hello', ' ONE TWO THREE' ,'student.two@toto.com'
DECLARE check_cursor CURSOR FOR select value from STRING_SPLIT(@list,',')
OPEN check_cursor
FETCH NEXT FROM check_cursor INTO @val
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @val
IF EXISTS (select * from #student where REPLACE(FIRST_NAME, ' ','')
like '%' + @val + '%' OR REPLACE(LAST_NAME, ' ','') like '%' + @val + '%')
BEGIN
INSERT INTO #table (FIRST_NAME, LAST_NAME )
SELECT TOP 1 FIRST_NAME, LAST_NAME VALUE from #student where
REPLACE(FIRST_NAME, ' ','') like '%' + @val + '%' OR REPLACE(LAST_NAME, ' ','')
like '%' + @val + '%'
END;
FETCH NEXT FROM check_cursor INTO @val
END
CLOSE check_cursor;
DEALLOCATE check_cursor;
SELECT * FROM #table;
DROP TABLE #table;
DROP TABLE #student;
你被困在
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
输出:
x
----------
abcdefg
abc
(2 row(s) affected)
x
----------
abc
abcdefg
(2 row(s) affected)
在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服务器:
WHERE CONTAINS(t.something, '"bla*" OR "foo*" OR "batz*"')
要查询的列必须是全文索引的。
参考:
使用Oracle文本构建全文搜索应用程序
理解SQL Server全文
你甚至可以试试这个
函数
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
查询
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+'%';