sqlsql-serverreplace

Use Column value as string pattern in REPLACE function


I'm trying to strip off version suffixes (_v1...) from a whole bunch of app names.

For example, let's say I have the following data:

CREATE TABLE applications 
 (
   name varchar(20)
 );

INSERT INTO applications
 (name)
VALUES
 ('MyApp_v2'),
 ('MyApp_v1'),
 ('MyApp'),
 ('YourApp_R1');

I could normally do this by nesting a lot of replace statements:

SELECT REPLACE(REPLACE(REPLACE(
         name,
       '_R1', ''),
       '_v2', ''),
       '_v1', '')
       As AppNameWithoutSuffix
FROM applications

But I have a lot of version numbers to check for, so I was hoping for something cleaner. Based on the following questions:

I wanted to create a CTE that stored all the prefixes and then REPLACE them all like this:

;WITH versions (suffix) AS (
    SELECT '_R1' UNION ALL
    SELECT '_v2' UNION ALL
    SELECT '_v1'
)
SELECT REPLACE(a.name, v.suffix, '') As AppNameWithoutSuffix
FROM applications a,
     versions v

But this does not quite work. The multiple from statements gives me the cartesian product of both tables and only strips out the suffix on the rows where the value happens to line up.

Demo in Sql Fiddle

Note: I know I could convert this to a function, but I'd rather keep everything within a single query if possible.


Solution

  • This does it:

    ;WITH versions (suffix) AS (
        SELECT '_R1' UNION ALL
        SELECT '_v2' UNION ALL
        SELECT '_v1'
    )
    SELECT  name, 
            REPLACE(A.name,ISNULL(B.suffix,''),'') VersionlessName
    FROM applications A
    LEFT JOIN versions B
        ON A.name LIKE '%'+B.suffix
    

    The results are:

    ╔════════════╦═════════════════╗
    ║    name    ║ VersionlessName ║
    ╠════════════╬═════════════════╣
    ║ MyApp_v2   ║ MyApp           ║
    ║ MyApp_v1   ║ MyApp           ║
    ║ MyApp      ║ MyApp           ║
    ║ YourApp_R1 ║ YourApp         ║
    ╚════════════╩═════════════════╝
    

    And here is the modified sqlfiddle.