[英]MySQL sorting table by column names
I have already built a table with field names in arbitrary order. 我已经用任意顺序的字段名称构建了一个表。 I want those field names to be in alphabetical order so that I can use them in my dropdown list.
我希望这些字段名称按字母顺序排列,以便可以在下拉列表中使用它们。 Is it possible with a query?
查询可能吗?
Select columns from a specific table using INFORMATION_SCHEMA.COLUMNS
and sort alphabetically with ORDER BY
: 使用
INFORMATION_SCHEMA.COLUMNS
从特定表中选择列,并使用ORDER BY
按字母顺序排序:
SELECT column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema = '[schemaname]'
AND table_name = '[tablename]'
ORDER BY column_name
This should do the trick. 这应该可以解决问题。 It's a bit messy and lengthy, and you'll have to change the database name and table name, but for this one, the only requirement is that there is a database named "test" and that you are running these commands in it:
这有点麻烦且冗长,您必须更改数据库名称和表名称,但是对于此数据库,唯一的要求是存在一个名为“ test”的数据库,并且您要在其中运行以下命令:
Let's create the tables we need: 让我们创建所需的表:
-- 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)
);
Now let's create the two stored procedures required for this to work: 现在,让我们创建两个工作所需的存储过程:
Separating them since one will be responsible for loading the commands, and including a cursor to immediately work with it isn't plausible (at least for me and my mysql version): 将它们分开,因为一个人将负责加载命令,并包括一个游标以立即使用它(至少对我和我的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:=@rankalter+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:=@rankmain+1 AS rownum, position FROM (
SELECT 0 AS rownum, 'FIRST' AS position
, '' AS columnname
UNION
SELECT @rank:=@rank+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 ;
If anyone thinks/sees that I'm missing to include any important column attributes in the ALTER
command, please hesitate not and mention it! 如果有人认为/发现我在
ALTER
命令中缺少任何重要的列属性,请不要犹豫,并提及它! Now to the next procedure. 现在转到下一个步骤。 This one just executes the commands following the order of column
id
from the loadcommands
table. 这只是按照
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 ;
The SQL is long, so if someone can point out ways (and has tested them) to make this shorter I'd gladly do it, but for now, this at least works on my end. SQL很长,因此,如果有人可以指出(并对其进行了测试)使其更短,我会很乐意这样做,但是就目前而言,这至少对我有效。 I also didn't need to put dummy data in the
alphabet
table. 我也不需要将虚拟数据放在
alphabet
中。 Checking the results can be done using the SHOW...
command. 可以使用
SHOW...
命令检查结果。
The last part: 最后一部分:
-- 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
Perhaps later on I could make reorder_loadcommands
dynamic and accept table and schema parameters, but I guess this is all for now.. 也许以后我可以使
reorder_loadcommands
动态化并接受表和模式参数,但是我想这一切现在都已解决。
this must help 这必须有所帮助
ALTER table `table_name`
MODIFY COLUMN `Field1` varchar(100)
AFTER `Field2`
you will get Field1 after Field2 您将在Field2之后得到Field1
ie 即
Field2 场2
Field1 场1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.