I am looking to combine the following two LIKE
string comparisons into one LIKE
string comparison:
SELECT *
FROM dbo.Departments D
WHERE D.SystemKey LIKE 'SCI%'
OR D.SystemKey LIKE 'FOO%';
I have tried the following, thinking that the combination of square brackets and the pipe (vertical bar) character could return system keys starting either 'SCI' or 'FOO':
SELECT *
FROM dbo.Departments D
WHERE D.SystemKey LIKE '[SCI|FOO]%';
Instead, this returns all rows with a SystemKey starting 'S', 'C', 'I', '|', 'F', or 'O'.
In the example I've given, I could use the following:
SELECT *
FROM dbo.Departments D
WHERE LEFT(D.SystemKey, 3) IN('SCI','FOO');
However, I would like to know if this can be done in a single string comparison using the LIKE
operator.
Below is some of the code I used to create a database table with data to query against for the purpose of this post:
CREATE TABLE dbo.Departments (
DepartmentID int IDENTITY(1,1) PRIMARY KEY,
SystemKey nvarchar(10),
Description nvarchar(50)
);
GO
INSERT dbo.Departments (
SystemKey,
Description
)
SELECT V.SystemKey,
V.Description
FROM ( VALUES (N'SCI001', N'Science 1'), (N'SCI010', N'Science 2'), (N'SCI011', N'Science 3'),
(N'MAT001', N'Mathematics 1'), (N'MAT010', N'Mathematics 2'), (N'MAT011', N'Mathematics 3'),
(N'SPA001', N'Spanish 1'), (N'SPA010', N'Spanish 2'), (N'SPA011', N'Spanish 3'),
(N'FOO001', N'Food Technology 1'), (N'FOO010', N'Food Technology 2'), (N'FOO011', N'Food Technology 3'),
(N'CAL001', N'Calisthenics 1'), (N'CAL010', N'Calisthenics 2'), (N'CAL011', N'Calisthenics 3')
) AS V(SystemKey, Description);
GO
Finally, the following solution would work with the data in the example but could return additional results if, for example, there was a SystemKey starting 'FCO':
SELECT *
FROM dbo.Departments D
WHERE D.SystemKey LIKE '[SF][CO][IO]%';
Note. This question was marked as a duplicate but the linked question is specifically about the use of RegEx in SQL Server. This question focuses on the limited pattern-matching syntax that the LIKE expression offers.
OR
is the correct solution. A pipe (|
) is just a pipe (|
) with SQL Server's rudimentary pattern matching; it's not Regex.
The alternative would be to use a set of values/patterns by use of a VALUES
clause, or a table type parameter/variable, and JOIN
to that or use an EXISTS
against it:
SELECT D.* --Should be a specific list of columns
FROM dbo.Departments D
JOIN (VALUES('SCI'),('FOO'))V(String) ON D.SystemKey LIKE V.String + '%';
DECLARE @TableVariable table (Pattern varchar(30) PRIMARY KEY); --So it's indexed
INSERT INTO @TableVariable
VALUES('SF%'),('CO%'),('IO%');
SELECT D.* --Should be a specific list of columns
FROM dbo.Departments D
WHERE EXISTS (SELECT 1
FROM @TableVariable TV
WHERE D.SystemKey LIKE TV.Pattern);