sqlsql-serversql-like

Use of Pipe (Vertical bar) in SQL LIKE operator statements


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.


Solution

  • 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);
    

    db<>fiddle