2014-12-11 42 views
0

我知道那裏已經有一些相同的問題了,但是這個問題讓我很困惑。只在sql上選擇數字值

我有這個疑問:

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 

我想從查詢得到的是:

  1. 如果location_name不包含任何數值,然後返回1
  2. 如果location_name包含數字值,則只獲取最後一個數值(在字符串後),即 即c2傳送帶10應僅返回10
  3. 如果location_name只包含數值,然後返回1

但我得到的是這樣的:

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 

是否有可能做到這一點的SQL?

+0

mysql'regex'只返回'Boolean'你不能用正則表達式替換/過濾文本,你應該創建自定義的字符串操作函數來提取結果 – Girish 2014-12-11 06:06:29

+0

看起來像http://stackoverflow.com/q/5651949/ 4099598。 – 2014-12-11 06:11:41

+0

看看我的答案。我認爲這正是你想要的。 – Veera 2014-12-11 07:10:05

回答

1

試試這個:(我認爲這將返回預期的結果,否則記你會得到什麼。)

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

這是不好的,當你突然變更後的標籤MySQL來PGSQL。我所有的作品都浪費了。

這裏是PGSQL代碼:

創建一個函數來檢查ISDIGIT():

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

然後這裏是代碼:

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.

+0

哇,這太好了,但爲什麼我得到'提示:沒有函數匹配給定的名稱和參數類型。你可能需要添加明確的類型轉換。(它指向REVERSE)? – 2014-12-12 01:38:41

+0

btw我在postgresql中創建了一個小提琴:http://www.sqlfiddle.com/#!11/d6a27/2 – 2014-12-12 01:40:19

+0

我改變了我對PgSQL的答案,並添加了演示鏈接。 – Veera 2014-12-12 06:19:08

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 
+0

OP已將標記從mysql切換到postgresql,因此我認爲您的答案不再適用。 – 2014-12-12 01:55:29