订单在oracle上的varchar上

时间:2015-08-14 07:02:33

标签: java mysql oracle

以下是我的一个表(MyTABLE)的列数据(ORDER),

a
a.1
a.1.1
a.2.0
a.1.10
a.1.4
a.20.1
a.2.2.1
a.4.3.1
a.4
a.40

我想以下面的方式订购,

a
a.1
a.1.1
a.1.4
a.2.0
a.2.2.1
a.4
a.4.3.1
a.20.1
a.40
b.*....(if any data present which has b prefixed etc.,)

我想知道在获取结果时是否可以在数据库级别实现这一点?如果没有那么我们将如何在java中做到这一点?

2 个答案:

答案 0 :(得分:3)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE MyTable ( name ) AS
          SELECT 'a' FROM DUAL
UNION ALL SELECT 'a.1.4' FROM DUAL
UNION ALL SELECT 'a.2.2.1' FROM DUAL
UNION ALL SELECT 'a.1.1' FROM DUAL
UNION ALL SELECT 'a.1' FROM DUAL
UNION ALL SELECT 'a.40' FROM DUAL
UNION ALL SELECT 'a.4' FROM DUAL
UNION ALL SELECT 'a.4.3.1' FROM DUAL
UNION ALL SELECT 'a.20.1' FROM DUAL
UNION ALL SELECT 'b.1' FROM DUAL
UNION ALL SELECT 'a.2.0' FROM DUAL

查询1

SELECT *
FROM   MyTable
ORDER BY
       REGEXP_SUBSTR( name, '[^.]+', 1, 1 ),
       TO_NUMBER( REGEXP_SUBSTR( name, '[^.]+', 1, 2 ) ) NULLS FIRST,
       TO_NUMBER( REGEXP_SUBSTR( name, '[^.]+', 1, 3 ) ) NULLS FIRST,
       TO_NUMBER( REGEXP_SUBSTR( name, '[^.]+', 1, 4 ) ) NULLS FIRST

<强> Results

|    NAME |
|---------|
|       a |
|     a.1 |
|   a.1.1 |
|   a.1.4 |
|   a.2.0 |
| a.2.2.1 |
|     a.4 |
| a.4.3.1 |
|  a.20.1 |
|    a.40 |
|     b.1 |

SQL Fiddle

MySQL 5.6架构设置

CREATE TABLE MyTable ( name VARCHAR(20) );

INSERT INTO MyTable
          SELECT 'a' FROM DUAL
UNION ALL SELECT 'a.1.4' FROM DUAL
UNION ALL SELECT 'a.2.2.1' FROM DUAL
UNION ALL SELECT 'a.1.1' FROM DUAL
UNION ALL SELECT 'a.1' FROM DUAL
UNION ALL SELECT 'a.40' FROM DUAL
UNION ALL SELECT 'a.4' FROM DUAL
UNION ALL SELECT 'a.4.3.1' FROM DUAL
UNION ALL SELECT 'a.20.1' FROM DUAL
UNION ALL SELECT 'b.1' FROM DUAL
UNION ALL SELECT 'a.2.0' FROM DUAL;

查询1

SELECT name
FROM   MyTable
ORDER BY
       SUBSTRING_INDEX( name, '.', 1 ),
       CASE WHEN SUBSTRING_INDEX( name, '.', 2 ) = SUBSTRING_INDEX( name, '.', 1 ) THEN -1 ELSE CAST( SUBSTRING_INDEX( SUBSTRING_INDEX( name, '.', 2 ), '.', -1 ) AS SIGNED ) END,
       CASE WHEN SUBSTRING_INDEX( name, '.', 3 ) = SUBSTRING_INDEX( name, '.', 2 ) THEN -1 ELSE CAST( SUBSTRING_INDEX( SUBSTRING_INDEX( name, '.', 3 ), '.', -1 ) AS SIGNED ) END,
       CASE WHEN SUBSTRING_INDEX( name, '.', 4 ) = SUBSTRING_INDEX( name, '.', 3 ) THEN -1 ELSE CAST( SUBSTRING_INDEX( SUBSTRING_INDEX( name, '.', 4 ), '.', -1 ) AS SIGNED ) END

<强> Results

|    name |
|---------|
|       a |
|     a.1 |
|   a.1.1 |
|   a.1.4 |
|   a.2.0 |
| a.2.2.1 |
|     a.4 |
| a.4.3.1 |
|  a.20.1 |
|    a.40 |
|     b.1 |

答案 1 :(得分:1)

这是有可能的,但建议您只有在熟悉数据并且可以处理数字格式例外的情况下才能这样做。

SELECT *
FROM TABLE
ORDER BY 
TO_NUMBER(SUBSTR( REPLACE(column,'a.'),1, 
        INSTR(REPLACE(column,'a.'),'.')
      ) ||
SUBSTR( REPLACE(column,'a.'), 
        INSTR(REPLACE(column,'a.'),'.'),
        LENGTH(REPLACE(column,'a.'))
      ))

如何按工作顺序:

  • 摆脱'a'。来自列值
  • 在'a'之后获取第一个数字。这将是1,2,4
  • 在1.之后的剩余字符串中,2。删除所有'。'
  • 最后你的数据应该是这个数字形式1.0,1.11,2.0,2.21,4.0,4.31

以上面的数字形式获取数据后,订单将按您的预期运作。

同样,这是非常具体的情况,您的数据可能比这更多模式。