4

mysqlで文字列を数値としてソートする方法を何日も探しました。

私の行は次のようになります。

order_column

1.1.2
1.1.100
1.1.1

mysql でこの列を昇順で並べると、次のようになります。

1.1.1
1.1.100
1.1.2

次の結果を得ることに興味があります。

1.1.1
1.1.2
1.1.100

SQL を使用してこの結果を生成する方法はありますか?

私の列の他の可能な値:

28.1999.1.1
1
1.1.154.20
100.1.1.1.1.15

ありがとう、みんなの時間をありがとう。

編集: ツリー データを格納する高速リレーショナル メソッド (記事のスレッド化されたコメントなど) Ayman Hourieh による最初の回答を見てください。私はそのソリューションを機能させようとしています。私のウェブサイトには、記事ごとに 10,000 件を超えるコメントがないため、次のような回避策を見つけました。

000001
000002
000002.000001
000002.000001.000001
000002.000002
000002.000003
000003

基本的に、文字列比較が失敗しないように、コメントカウンターの前にゼロを置きます。ただし、これは 99999 件のコメントに対してのみ機能します。さらにゼロを追加できます。たとえば、ゼロを 10 個追加すると、999999999 件のコメントに対して機能しますが、より洗練されたソリューションを期待していました。

4

10 に答える 10

4

文字列が長すぎない場合は、次のことができます

ORDER BY cast(replace(your_column_name,'.','') as unsigned);
于 2012-12-18T13:53:13.417 に答える
2

これはすべてのインデックスを見逃すため、これを効率的に行うことはできませんが、1回限りの場合は機能します。悲しいことに、MySQLが一度に複数の文字を置き換えることができない(私が知っている)ため、それは恐ろしいように見えます。

SELECT value FROM TEST ORDER BY 
   REPLACE(
    REPLACE(
      REPLACE(
        REPLACE(
          REPLACE(
            REPLACE(
              REPLACE(
                REPLACE(
                  REPLACE(value, 
                    '1', '0'),
                  '2', '0'), 
                '3', '0'), 
              '4', '0'), 
            '5', '0'), 
          '6', '0'), 
        '7', '0'), 
      '8', '0'), 
    '9', '0'),value;

基本的に、すべての数字を0に置き換え、最初に0で並べ替えます。0より前に注文するため.、数字グループで正しく注文されます。それが終わったら、同じ桁グループの値は正しい順序で並べ替える必要があるため、値で並べ替えるだけです。

これをより効率的にするために、置換された値をデータベースの列として格納して、インデックスを作成することができます。

SQLfiddleのデモはこちら

于 2012-12-18T15:04:51.333 に答える
1
SELECT INET_ATON('10.0.5.9');

あなたの中でこの関数を試してみてください:)

おそらく、それはIPアドレスタイプ専用であるため、代替手段ではありません。そして、IPアドレスよりも多くの部分があります。

于 2012-12-18T14:01:06.773 に答える
1

これは効率的ではなく、クリーンアップできますが、これを行う方法の 1 つのアイデアです。これは、値が 0 から 9 の 10 行の i という単一の列を持つ integers というテーブルに依存しています。

SELECT somefield    , SUM(POW(100, occurrences - anInteger) * somefield_split) OrderField
FROM
    (SELECT id,anInteger,  somefield, SUBSTRING_INDEX(SUBSTRING_INDEX(somefield, ".", anInteger), ".", -1) AS somefield_split, LENGTH(somefield) - LENGTH(REPLACE(somefield, '.', '')) + 1 AS occurrences
    FROM splittertest, (SELECT a.i*10+b.i AS anInteger FROM integers a, integers b) Sub1
    HAVING occurrences >= anInteger) Sub2
GROUP BY somefield
ORDER BY somefield, OrderField

アイデアは、副選択が0から99までの範囲の数値を取得し、これに基づいて文字列をドット区切りの値に分割することです。特定の文字列のドット数を取得します。次に、文字列の各ビットに 100 をセクションの総数からこのセクションの数を引いた値で乗算し、これに基づいて合計します。

したがって、5.10.15 は 5、10、および 15 に分割されます。3 つのセクションがあるため、最初のセクションは 100 の (3 - 0) 乗、2 番目のセクションは 100 の (2 - 0) 乗などになります。 .

これは、ドットの数が異なる場合に奇妙な結果をもたらします (つまり、より多くのドットを持つものは常に大きくなります)。しかし、これは、数ではなく、累乗を計算するときに任意の行のドットの最大数を使用することで修正できます。その特定の行のドットの。

頑張ってください!

于 2012-12-18T14:38:14.807 に答える
0

次のSQLを使用できます

SELECT REPLACE(column_name,'.','') AS column_name1 FROM table_name ORDER BY column_name1;
于 2012-12-18T14:00:04.353 に答える
0

最後の桁のグループで注文している場合は、

SELECT CAST(MID(order_column, 
CHAR_LENGTH(order_column) - 
LOCATE('.',REVERSE(order_column))+2) AS DECIMAL) AS order_column_as_number
FROM thetable 
ORDER BY order_column_as_number

うまくいくようです。

'。'のない文字列がある場合は、まったく機能しません。それらの中で、他のグループでも注文したい場合は、注文するパーツをさらに抽出する必要がありますが、SQLでのみ実行したい場合は、これが開始になる可能性があります。

于 2012-12-18T14:03:13.453 に答える
0

これらの数値の列がINTvarchar でないことを確認してください。

varchar を使用すると、列は最初に 1 を持つ人でソートされます...

于 2012-12-18T14:06:08.153 に答える
0

'.' の文字列置換を使用して、この列と等しい新しい列を作成します。'' (何もない)。この新しいフィールドを数値として保存します。クエリではなく、このフィールドで並べ替えます。

テーブルに新しい列を追加できない場合は、これを PHP などで処理して、たとえば Web サイトでの表示目的で同じ効果を得ることができます。

http://php.net/manual/en/function.str-replace.php
于 2012-12-18T13:51:34.347 に答える
0

ここで、最大4桁の数値の私のソリューション:

SELECT myCol, SUBSTRING_INDEX(myCol, ',', 1) * 10000 + LEFT(CONCAT(SUBSTRING_INDEX(myCol, ',', -1), '0000'), 4) as toOrder 
FROM `myTable`
ORDER BY toOrder DESC

次のように、小数点以下 8 桁で設定できます。

SELECT myCol, SUBSTRING_INDEX(myCol, ',', 1) * 100000000 + LEFT(CONCAT(SUBSTRING_INDEX(myCol, ',', -1), '00000000'), 8) as toOrder 
FROM `myTable`
ORDER BY toOrder DESC

等...

于 2019-05-21T13:55:34.107 に答える