2017-02-28 4 views
0

私はyear varchar(100)という名前のテーブルを持っています。この列はMySqlは数字のみを選択し、それらをvarcharカラムから注文します

Year 
------- 
1901 
    0 
circa 12580 
125d4 great 
year 1012 
3411 standard 
12 
    saf 
1234 

などのデータは、今私はYearフィールドに最初の4桁の数字を見つけることによってYear昇順または降順で注文したい含めることができます。私がしたい:

  1. はカラムだけものが4桁以上(単独で、または いくつかの文字列を含むいずれか)
  2. は最初の4桁の数字を抽出する(4つ以上またはいくつかの整数である場合)または4桁の数字を取得していなさい二つの条件

上記に基づき、結果セットによって

  • 注文を(列のみ4桁の値を持つ場合)、私は私の結果は以下のように昇順に設定したい:

    Year 
    1012 
    1234 
    1258 
    1901 
    3411 
    

    降順で逆も同様です。私は、次の試してみました

    SELECT * 
    FROM table 
    WHERE YEAR REGEXP '^[0-9]+$' AND LENGTH(YEAR) = 4 
    ORDER BY CAST(YEAR AS UNSIGNED) DESC; 
    

    しかし、これはそれらによってのみ4桁の数字と注文を持つ列を返しますが、ではない、私は上記のように結果。

  • +1

    ベストプラクティスは、int型を使用して新しい列を作成することです年を取って、それを並べ替えます。抽出された正規表現でソートするクエリを構築することは成功しますが、インデックスを使用しません(多くの行がある場合は重要です)。プロダクションアプリではないクエリの場合は、テンポラリテーブルを作成し、古いテーブルのすべての行と正規化された年の値を入力してから、通常のソートを行います。 –

    +0

    @DanIonescu私は現在生産中ですが、今すぐカラムを作成することはできません –

    +1

    okですので、クエリはアプリケーションのためですか、それとも一度データを分析するのは一度だけですか? –

    答えて

    1

    これは私が問題を解決した方法です。私は見えている(Ushastryから返信)hereからの助けを取るストアド・ファンクションを作成している

    CREATE FUNCTION `get_numeric`(`year` VARCHAR(50)) RETURNS INT(11) 
          NO SQL 
         BEGIN 
          DECLARE ctrNumber VARCHAR(50); 
          DECLARE finNumber VARCHAR(50) DEFAULT ' '; 
          DECLARE sChar VARCHAR(2); 
          DECLARE inti INTEGER DEFAULT 1; 
           IF LENGTH(year) > 0 THEN 
            WHILE(inti <= LENGTH(year)) DO 
             SET sChar= SUBSTRING(year,inti,1); 
               SET ctrNumber= FIND_IN_SET(sChar,'0,1,2,3,4,5,6,7,8,9'); 
    
               IF ctrNumber > 0 THEN 
              SET finNumber=CONCAT(finNumber,sChar); 
               ELSE 
              SET finNumber=CONCAT(finNumber,' '); 
               END IF; 
             SET inti=inti+1; 
            END WHILE; 
            RETURN finNumber; 
           ELSE 
            RETURN 'Invalid'; 
           END IF; 
         END 
    

    のようなそしてクエリが期待どおりに動作以下

    SELECT id, YEAR, SUBSTRING(`get_numeric`(YEAR),1,4) AS act_year FROM table HAVING LENGTH(act_year) = 4 ORDER BY act_year ASC; 
    
    関連する問題