views:

71

answers:

4

Is it possible to combine the CASE statement and the LIKE operator in a MySQL SELECT statement?

For Example, I am trying to query a database that stores data in a single column in either one of two formats (this is awful and hurts my head, but I cant change the data so it is what it is.). So sometimes the column numbers would have data like "6901xxxxxxxx" and sometimes it would have data like "91xxxxxxxxxxx".

What I would like to do is query the data like so -

SELECT
    CASE digits
      WHEN LIKE "6901%" THEN substr(digits,4)
      WHEN LIKE "91%" THEN substr(digits,2)
    END as "digits",
FROM raw

This obviously doesn't work but Im hoping its possible.

+2  A: 

Try

SELECT
    CASE true
      WHEN digits LIKE "6901%" THEN substr(digits,4)
      WHEN digits LIKE "91%" THEN substr(digits,2)
    END as "digits",
FROM raw
Tim
+1: I tested, this works. MySQL ignores the "true"; I thought it would trigger a syntax error. Still, I wouldn't add "true" in there if it wasn't necessary.
OMG Ponies
+1 for working, not quite as well as the accpeted answer :)
HurnsMobile
+3  A: 

Using the second form of CASE should work:

SELECT
  CASE
    WHEN digits LIKE '6901%' THEN substr(digits,4)
    WHEN digits LIKE '91%' THEN substr(digits,2)
  END as digits
FROM raw

Furthermore, you have a stray comma at the end of your SELECT.

Daniel Vandersluis
+1: `CASE column WHEN...` format is only good for exact matches; have to use this format for partial matches.
OMG Ponies
Ding ding ding, wrong form of case. Thanks a ton guys, my desk/forehead are grateful.
HurnsMobile
+1  A: 

Perhaps use LEFT()?

SELECT
    CASE 
      WHEN LEFT(digits, 4) = '6901' THEN substr(digits,4)
      WHEN LEFT(digits, 2) = '91' THEN substr(digits,2)
    END 
FROM raw

Should be more performant than the LIKE.

p.campbell
The LIKE in this example is only wildcarding the right side, so an index could be used but I don't believe that LEFT/INSTR could use an index. +1 for an alternative.
OMG Ponies
A: 

Assuming the number of digits is constant, you could use something like this:

SELECT IF(digits > 919999, MOD(digits, 100), MOD(digits, 10000) FROM raw

Add 0's to match your actual number of digits.

Joshua Martell