【问题标题】:ordering fields in a table upwards mysql向上排序表中的字段mysql
【发布时间】:2014-01-25 01:04:57
【问题描述】:

我有一个名为 user 的列。我有这样的字段:user1,user2,...,user10,user11,user12,user20。但字段并不总是由用户开始

我想将这些字段向上排序,即,我正在执行以下查询:

SELECT * FROM table ORDER BY user ASC

此查询返回: 用户1,用户10,用户11,用户12,用户2,用户20

我想要的排序如下: 用户1,用户2,用户11,用户12,用户20

我怎样才能做到这一点?我使用的编程语言是php

【问题讨论】:

  • 是否所有字段都包含user,然后是一个数字?

标签: php mysql sql select sql-order-by


【解决方案1】:

您可以使用 PHP 的自然排序函数 natsort() — 使用“自然顺序”算法对数组进行排序。

【讨论】:

  • 我怎样才能只为该列使用 natsort?由于查询返回了更多列
【解决方案2】:

您需要使用函数提取数字,然后按此排序

SELECT * FROM table ORDER BY numeric(user) ASC

这是一个快速的(从规范化函数修改)

CREATE FUNCTION `numeric`(`str` VARCHAR(255) )
    RETURNS varchar(255) CHARSET utf8
    LANGUAGE SQL
    DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN 
  DECLARE i, len SMALLINT DEFAULT 1; 
  DECLARE ret VARCHAR(255) DEFAULT ''; 
  DECLARE c VARCHAR(1);   
  SET len = CHAR_LENGTH( str ); 
  REPEAT 
    BEGIN 
      SET c = MID( str, i, 1 ); 
      IF c REGEXP '[[:digit:]]' THEN 
        SET ret=CONCAT(ret,c); 
      END IF; 
      SET i = i + 1; 
    END; 
  UNTIL i > len END REPEAT; 
  RETURN ret; 
END

【讨论】:

    【解决方案3】:

    试试这个用法CAST

    SELECT * FROM table ORDER BY CAST(SUBSTRING(user, 5) AS unsigned)
    

    检查 sqlfiddle http://sqlfiddle.com/#!2/5f307c/1

    【讨论】:

    • 结果:user1、user10、user2、user11 等
    • 谢谢!但并非这些领域并不总是以相同的方式开始。可以以其他字符开头
    • 它取决于字符串长度。如果上述情况 5 char 是数字
    【解决方案4】:

    如果数据中包含带有数字的单词user,则可以使用Mysql的SUBSTRING_INDEX

    SELECT 
      * 
    FROM
      TABLE 
    ORDER BY SUBSTRING_INDEX(`user`, 'user', - 1) ASC 
    

    【讨论】:

    • 字段可能有不同的名称和数字并不总是有
    【解决方案5】:

    怎么样

    SELECT * FROM test ORDER BY
       LPAD(lower(user), 10,0) ASC
    

    检查这里

    http://sqlfiddle.com/#!2/e49f2/16

    【讨论】:

    • 但字段的开头并不总是相同的。可以以其他字符开头
    【解决方案6】:

    最好再添加一个包含用户位置的列,然后按该列排序。但是如果你不能改变你的表结构,这样的查询应该以正确的顺序返回你的行:

    SELECT
      tablename.*
    FROM
      tablename
    ORDER BY
      SUBSTR(user,
      LEAST(
        CASE WHEN LOCATE('0', user)>0 THEN LOCATE('0', user) ELSE LENGTH(user) END,
        CASE WHEN LOCATE('1', user)>0 THEN LOCATE('1', user) ELSE LENGTH(user) END,
        CASE WHEN LOCATE('2', user)>0 THEN LOCATE('2', user) ELSE LENGTH(user) END,
        CASE WHEN LOCATE('3', user)>0 THEN LOCATE('3', user) ELSE LENGTH(user) END,
        CASE WHEN LOCATE('4', user)>0 THEN LOCATE('4', user) ELSE LENGTH(user) END,
        CASE WHEN LOCATE('5', user)>0 THEN LOCATE('5', user) ELSE LENGTH(user) END,
        CASE WHEN LOCATE('6', user)>0 THEN LOCATE('6', user) ELSE LENGTH(user) END,
        CASE WHEN LOCATE('7', user)>0 THEN LOCATE('7', user) ELSE LENGTH(user) END,
        CASE WHEN LOCATE('8', user)>0 THEN LOCATE('8', user) ELSE LENGTH(user) END,
        CASE WHEN LOCATE('9', user)>0 THEN LOCATE('9', user) ELSE LENGTH(user) END
        )) + 0
    

    请看小提琴here

    【讨论】:

    • 字段并不总是以用户开头:/
    • @pc_oc 是的,用户是列名所以应该没问题,在这里看到它sqlfiddle.com/#!2/4d8ad/1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-26
    • 2015-06-21
    • 1970-01-01
    • 2012-10-24
    • 2011-07-01
    • 1970-01-01
    • 2012-07-06
    相关资源
    最近更新 更多