2012-07-18 58 views
0

我在這個名爲MM的列中有這個數字4.40-4.85X3.60。如何在mysql查詢中複雜的數字之間進行搜索?

我想搜索器,可通過MySQL的更大或低於3點從每個編號爲exampel號碼:

[4.37-4.43] - ,之後[4.82-4.88] X [0-9]的數X可以是任何數字。

我試過使用正則表達式,但我沒有找到真正有用的東西,請告知。

+0

哪些正則表達式不起作用?示例 – 2012-07-18 15:58:44

+1

'4.40-4.85X3.60'不是數字 – Shikiryu 2012-07-18 15:59:52

+0

正則表達式不是正確的選擇,你最好使用sql字符串函數將列值分成三部分,然後檢查這些值是否在範圍內。 – 2012-07-18 16:01:13

回答

0

一種方法是將字符串「拆分」,以便從中獲取所需的單獨組件。假設該字符串總是使用「 - 」和「X」的三個組成部分,在此查詢表達式分離將「拆分」它給你:

SELECT SUBSTRING_INDEX(@n,'-',1) AS s1 
    , SUBSTRING_INDEX(SUBSTRING_INDEX(@n,'-',-1),'X',1) AS s2 
    , SUBSTRING_INDEX(@n,'X',-1) AS s3 
    FROM (SELECT @n := '4.40-4.85X3.6') n 

然後可以在每次這些表達式轉換爲數值。

請注意,MySQL可能會(默默地)丟失精度數字,可能返回「0」表示無法轉換爲數字的字符串,或者MySQL可能會拋出異常或警告。

因此,請謹慎選擇DECIMAL(m,n)的比例和精度,以避免溢出並正確處理舍入/截斷。您示例中顯示的所有數據都適合DECIMAL(3,2),但這僅僅是一個示例,並不是所有數據的保證。

我會在內聯視圖中執行「搜索參數」字符串的轉換,然後將它加入到要搜索的表中。

事情是這樣的:

SELECT t.MM 
    FROM mytable t 
    JOIN (SELECT CONVERT(SUBSTRING_INDEX(@n,'-',1)      ,DECIMAL(6,2)) AS s1 
      , CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(@n,'-',-1),'X',1),DECIMAL(6,2)) AS s2 
      , CONVERT(SUBSTRING_INDEX(@n,'X',-1)      ,DECIMAL(6,2)) AS s3 
      FROM (SELECT @n := '4.40-4.85X3.6') n 
     ) p 
    ON ABS(p.s1 - CONVERT(SUBSTRING_INDEX(t.MM,'-',1),DECIMAL(6,2))) 
     <= .03 
    AND ABS(p.s2 - CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(t,MM,'-',-1),'X',1),DECIMAL(6,2)) 
     <= .03 

連接謂詞是距離搜索參數減去(衍生)數值從表中從(衍生)數值值,檢查差異的問題。

同樣,正如我之前提到的,在轉換爲DECIMAL操作的情況下,請注意字符串不是預期格式的問題,太大而不適合縮放(溢出)的值以及舍入/截斷。你可能會得到意想不到的結果(MySQL可能會失去精度並且無聲無息地伸縮,或者可能會拋出異常和/或警告。(行爲取決於會話的sql_mode設置。)

2

對這三個數字使用單獨的列,這將解決您的所有問題。

否則,使用類似:

WHERE 
    CAST(SUBSTR(MM FROM 1 FOR (@tmp1:=POSITION("-" IN MM))) AS DECIMAL(3,2)) 
     BETWEEN 4.37 AND 4.43 
    AND 
    CAST(SUBSTR(MM FROM @tmp1 FOR POSITION("X" IN MM)[email protected]) AS DECIMAL(3,2)) 
     BETWEEN 4.82 AND 4.88 

,但請記住,這對你可能對你的表的任何索引完全螺絲。

+0

將它分解爲搜索'-'和'X'在字符串中的位置以及那三個部分然後檢查(用'between')的部分會更好 - – 2012-07-18 16:05:27

+0

@Ωmega也許,我只是假設數字是定點的,但是如果它們是10或更高,那麼它又會如何。好的,將會被編輯。 – 2012-07-18 16:07:37