0

I know there is already some of the same questions out there, but this one is confusing me.

I have this query :

SELECT 
    CASE
    WHEN COALESCE(substring(location_name FROM '[0-9]+'), location_name) != '' 
    THEN COALESCE(substring(location_name FROM '[0-9]+'), location_name)
    ELSE '1'
END AS sequence
FROM LOCATION

What I would like to get from that query is :

  1. If the location_name doesn't contains any numeric values, then return 1
  2. If the location_name contains numeric values, get only the last numeric values (after string), i.e. c2 carousel 10, should return only 10
  3. If the location_name contains only numeric values, then return 1

But what I get is something like :

location_name   expected result     what I get
                                    using [0-9]         using [0-9]+
carousel 1      1                   1                   1
carousel 2      2                   2                   2
carousel 3      3                   3                   3
carousel 12     12                  1                   12
bottom banner   1                   bottom banner       bottom banner
c2 carousel 1   1                   2                   2
c2 carousel 3   3                   2                   2
59977           1                   5                   59977

Is it possible to do this in sql?

3
  • mysql regex return only Boolean you can't replace/filter text using regex, you should create custom string manipulation function to extract result Commented Dec 11, 2014 at 6:06
  • Looks a fair bit like stackoverflow.com/q/5651949/4099598. Commented Dec 11, 2014 at 6:11
  • Take a look at my answer. I think it is what exactly you want. Commented Dec 11, 2014 at 7:10

2 Answers 2

1

Try this: (I think it will return the expected result. Else make a note what you get.)

SELECT location_name, 
CASE WHEN concat('',location_name * 1) = location_name THEN
     1
WHEN concat('',reverse(substring_index(reverse(location_name), ' ', 1)) * 1) = reverse(substring_index(reverse(location_name), ' ', 1)) THEN
    reverse(substring_index(reverse(location_name), ' ', 1))
ELSE
    1
END AS EXPECTED_RESULT
FROM YourTable

--Quick Demo here:MySQL

It is not good when you suddenly changed the tag MYSql to PgSQL. All my works got waste.

Here is the PgSQL code:

Create a function to check isdigit():

create function isdigits(text) returns boolean as '
select $1 ~ ''^(-)?[0-9]+$'' as result
' language sql;

Then here is the code:

   SELECT location_name, 
      CASE WHEN isdigits(location_name) = true THEN 1
           WHEN isdigits(substr(location_name, length(regexp_replace(location_name, '\\s\\S+$', '')) + 2)) = true THEN 
                substr(location_name, length(regexp_replace(location_name, '\\s\\S+$', '')) + 2)::int
           ELSE 1
      END AS Result
    FROM YourTable

--Quick Demo - PGSQL.

Sign up to request clarification or add additional context in comments.

2 Comments

Wow it's great, but why I get HINT: No function matches the given name and argument types. You might need to add explicit type casts. (it's pointing to REVERSE) ?
I changed my answer for PgSQL and added link for demo too.
0
-- Create one function first which will help to check wether value is numeric or not

CREATE FUNCTION mysql_IsNumeric(val TEXT) RETURNS int(11)
RETURN val REGEXP '^(-|\\+){0,1}([0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+|[0-9]+)$';

--create function that return numeric values only    
CREATE FUNCTION mysql_NumericOnly(val TEXT) RETURNS text CHARSET latin1
BEGIN  
DECLARE idx INT DEFAULT 0;  
IF mysql_IsNumeric(val) = 0 THEN  
IF ISNULL(val) THEN RETURN NULL; END IF;  
IF LENGTH(val) = 0 THEN RETURN ""; END IF;  
SET idx = LENGTH(val);  
WHILE idx > 0 DO   
IF strcmp(SUBSTRING(val,idx,1),'.')!=0  and mysql_IsNumeric(SUBSTRING(val,idx,1)) = 0 THEN  
SET val = REPLACE(val,SUBSTRING(val,idx,1),"");  
SET idx = LENGTH(val)+1;  
END IF;  
SET idx = idx - 1;  
END WHILE;  
END IF;  
RETURN val;  
END;


select *,
 case when mysql_IsNumeric(location_name)=1 then 1
 case when location_name!=mysql_NumericOnly(location_name) THEN
mysql_NumericOnly(Reverse(Left(REVERSE(location_name),INSTR(REVERSE(location_name),' ')))
  else 1 end as reselut    
  from YourTable

1 Comment

The OP has switched the tags from mysql to postgresql so I don't think your answers applies anymore.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.