2011-11-21 341 views
0

我已經按照任意順序構建了一個包含字段名的表。我希望這些字段名稱按字母順序排列,以便我可以在我的下拉列表中使用它們。查詢有可能嗎?MySQL按列名排序表

+1

這可以很容易地用JavaScript或呈現HTML語言來完成。而且它不是在SQL中想要的。大多數情況下,每行都會在散列表中讀取,順序將消失。 – newtover

+0

此外,依靠'SELECT *'不是一個好主意,在更改表定義 – newtover

回答

1

注:下面的代碼將改變指定的表和按字母順序重新排序的列


這應該可以做到。這有點麻煩和冗長,你必須更改數據庫名稱和表名,但是對於這個,唯一的要求是有一個名爲「test」的數據庫,並且你正在其中運行這些命令:

讓我們創建我們需要的表:

-- CREATE TESTING TABLE IN A DATABASE NAMED "test" 
DROP TABLE IF EXISTS alphabet; 
CREATE TABLE alphabet (
     d varchar(10) default 'dee' not null 
    , f varchar(21) 
    , e tinyint 
    , b int NOT NULL 
    , a varchar(1) 
    , c int default '3' 
); 

-- USE A COMMAND STORAGE TABLE 
DROP TABLE IF EXISTS loadcommands; 
CREATE TABLE loadcommands (
     id INT NOT NULL AUTO_INCREMENT 
    , sqlcmd VARCHAR(1000) 
    , PRIMARY KEY (id) 
); 

現在讓我們創建工作需要這種兩個存儲過程:

將它們分開,因爲一會負責加載命令,包括光標立即使用它是不合理的(至少對我和我的MySQL版本):

-- PROCEDURE TO LOAD COMMANDS FOR REORDERING 
DELIMITER // 
CREATE PROCEDURE reorder_loadcommands() 
BEGIN 
    DECLARE limitoffset INT; 
    SET @rank = 0; 
    SET @rankmain = 0; 
    SET @rankalter = 0; 
    SELECT COUNT(column_name) INTO limitoffset 
     FROM INFORMATION_SCHEMA.COLUMNS 
     WHERE table_schema = 'test' 
     AND table_name = 'alphabet'; 

    INSERT INTO loadcommands (sqlcmd) 
    SELECT CONCAT(t1.cmd, t2.position) AS commander FROM (
     SELECT @rankalter:[email protected]+1 AS rankalter, CONCAT('ALTER TABLE ' 
      , table_name, ' ' 
      , 'MODIFY COLUMN ', column_name, ' ' 
      , column_type, ' ' 
      , CASE 
       WHEN character_set_name IS NOT NULL 
        THEN CONCAT('CHARACTER SET ', character_set_name, ' COLLATE ', collation_name, ' ') 
       ELSE ' ' 
       END 
      , CASE 
       WHEN is_nullable = 'NO' AND column_default IS NULL 
        THEN 'NOT NULL ' 
       WHEN is_nullable = 'NO' AND column_default IS NOT NULL 
        THEN CONCAT('DEFAULT \'', column_default, '\' NOT NULL ') 
       WHEN is_nullable = 'YES' THEN 'DEFAULT NULL ' 
       END 
      ) AS cmd 
      , column_name AS columnname 
     FROM INFORMATION_SCHEMA.COLUMNS 
     WHERE table_schema = 'test' 
     AND table_name = 'alphabet' 
     ORDER BY columnname 
    ) t1 
    INNER JOIN (
     SELECT @rankmain:[email protected]+1 AS rownum, position FROM (
      SELECT 0 AS rownum, 'FIRST' AS position 
       , '' AS columnname 
      UNION 
      SELECT @rank:[email protected]+1 AS rownum, CONCAT('AFTER ', column_name) AS position 
       , column_name AS columnname 
      FROM INFORMATION_SCHEMA.COLUMNS 
       WHERE table_schema = 'test' 
       AND table_name = 'alphabet' 
      ORDER BY columnname 
      LIMIT limitoffset 
     ) inner_table 
    ) t2 ON t1.rankalter = t2.rownum 

    ; 

END// 
DELIMITER ; 

如果有人認爲/我看到我錯過了在ALTER命令中包含任何重要的列屬性,請不要猶豫,並提及它!現在到下一個程序。該命令只執行loadcommands表中列id的命令。 :

-- PROCEDURE TO RUN EACH REORDERING COMMAND 
DELIMITER // 
CREATE PROCEDURE reorder_executecommands() 
BEGIN 
    DECLARE sqlcommand VARCHAR(1000); 
    DECLARE isdone INT DEFAULT FALSE; 

    DECLARE reorderCursor CURSOR FOR 
    SELECT sqlcmd FROM loadcommands ORDER BY id; 

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET isdone = TRUE; 

    OPEN reorderCursor; 
    read_loop:LOOP 
     FETCH reorderCursor INTO sqlcommand; 

     IF isdone THEN 
      LEAVE read_loop; 
     END IF; 

     SET @sqlcmd = sqlcommand; 
     PREPARE stmt FROM @sqlcmd; 
     EXECUTE stmt; 
     DEALLOCATE PREPARE stmt;   

    END LOOP read_loop; 

    CLOSE reorderCursor;  
END// 
DELIMITER ; 

的SQL長,所以如果有人能指出方式(並測試了它們),使這個短我會很樂意這樣做,但現在,這至少工作在我結束。我也不需要在alphabet表中輸入虛擬數據。檢查結果可以使用SHOW...命令完成。

最後一部分:

-- TO TEST; AFTER RUNNING DDL COMMANDS: 

SHOW CREATE TABLE alphabet;  -- SEE ORIGINAL ORDER 
CALL reorder_loadcommands(); -- PREPARE COMMANDS 
CALL reorder_executecommands(); -- RUN COMMANDS 
SHOW CREATE TABLE alphabet;  -- SEE NEW ORDER 

也許以後我可以做reorder_loadcommands動態,並接受表和模式的參數,但我想這是所有現在...

6

使用INFORMATION_SCHEMA.COLUMNS和按字母順序排序,從一個特定的表選擇列與ORDER BY

SELECT column_name 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE table_schema = '[schemaname]' 
    AND table_name = '[tablename]' 
    ORDER BY column_name 
+0

後,最終會出現一些有趣的錯誤,但這並未改變它們的順序。我是否必須在我的php查詢中做到這一點,讓他們訂購? – huroran

+0

奇怪的是,我測試了查詢,它在這裏工作...也許顯示您的查詢代碼 –

+1

當然,你需要在你的查詢從PHP做到這一點。注意:您不會更改存儲的項目順序,我相信這是您一直在尋找的項目。存儲行的順序是由DBMS任意/處理的,您只能應用每個查詢的順序。 – Jules

-1

這必須幫助

ALTER table `table_name` 
    MODIFY COLUMN `Field1` varchar(100) 
    AFTER `Field2` 

你會得到Field1 after Field2


字段2
字段1