0

MM という列にこの数値 4.40-4.85X3.60 があります。

例として、mysql を使用して、各数値から 3 ポイント大きいか小さい数値を検索したい:

[4.37-4.43]-[4.82-4.88]X[0-9] 、X の後の数字は任意の数字です。

正規表現を使用してみましたが、実際に機能するものはありませんでした。アドバイスしてください。

4

2 に答える 2

2

3 つの数値に別々の列を使用すると、すべての問題が解決します。

それ以外の場合は、次のようなものを使用します:

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)-@tmp1) AS DECIMAL(3,2))
        BETWEEN 4.82 AND 4.88

ただし、これにより、テーブルにあるインデックスが完全に台無しになることに注意してください。

于 2012-07-18T15:58:38.087 に答える
0

1 つの方法は、その文字列を「分割」して、必要な個別のコンポーネントを取得することです。文字列が常に「-」と「X」を使用して 3 つのコンポーネントを区切ると仮定すると、このクエリの式はそれを「分割」します。

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

JOIN 述語は、検索パラメーターの (派生した) 数値からテーブルの (派生した) 数値を引き、その差を確認するだけです。

繰り返しますが、前に述べたように、DECIMAL 操作への変換では、想定された形式ではない文字列、スケールに適合するには大きすぎる値 (オーバーフロー)、および丸め/切り捨ての問題に注意してください。予期しない結果が生じる可能性があります (MySQL は精度を失い、サイレントにスケーリングするか、例外や警告をスローする可能性があります (動作はセッションの sql_mode 設定に依存します)。

于 2012-07-18T16:18:32.137 に答える