按字母顺序列出SQL所有的列名

31
我知道。
SELECT * FROM Table

以下代码将列出表中的所有列,但我希望按字母顺序列出列。

假设我有三个列,“name”,“age”和“sex”。

我想以以下格式组织列:

|age| |name| |sex|

使用SQL可以实现这个吗?

9个回答

19

这将生成一个查询,在选择语句中按字母顺序排列所有列。

DECLARE @QUERY VARCHAR(2000)
DECLARE @TABLENAME VARCHAR(50) = '<YOU_TABLE>'

SET @QUERY = 'SELECT '
SELECT @QUERY = @QUERY + Column_name + ', 
'
  FROM INFORMATION_SCHEMA.COLUMNS 
 WHERE TABLE_NAME = @TABLENAME
 ORDER BY Column_name

SET @QUERY =  LEFT(@QUERY, LEN(@QUERY) - 4) + ' 
FROM '+ @TABLENAME

PRINT @QUERY
EXEC(@QUERY)

1
这假设查询将始终以 ad-hoc 方式运行,但如果发布者接受动态 SQL,则也是一个很好的起点。 - RThomas
2
这个修订版对我有用,将Left语句(len)更改为-1。 - Brian

15

是的,也不是。

SQL本身并不关心列的输出顺序,但是,如果你使用:

select age, name, sex from ...

如果你执行这些语句,你会发现它们可能按照那个顺序输出(尽管我不确定 SQL 标准是否要求这样做)。

现在,你可能不希望这样做,但有时生活就是不公平的:-)

你还有另一种可能性,就是使用数据库管理系统数据定义表来动态构建查询。这是非可移植的,但大多数数据库管理系统都提供这些表(例如 DB/2 的 SYSIBM.SYSCOLUMNS),你可以按照一定的顺序从中选择列名。像这样:

select column_name from sysibm.syscolumns
where owner = 'pax' and table_name = 'movies'
order by column_name;

然后您使用查询的结果构建真实查询:

query1 = "select column_name from sysibm.syscolumns" +
         " where owner = 'pax' and table_name = 'movies'" +
         " order by column_name"
rs = exec(query1)
query2 = "select"
sep = " "
foreach colm in rs:
    query2 += sep + colm["column_name"]
    sep = ", "
query2 += " from movies order by rating"
rs = exec(query2)
// Now you have the rs recordset with sorted columns.

然而,你真的应该批判性地检查选择*的所有查询 - 在绝大多数情况下,这是不必要且低效的。数据的呈现可能应该由表示层执行,而不是DBMS本身 - DBMS应该尽可能高效地返回数据。


嗯,我想我得诉诸于老方法自己做字符串排序了 :) - Shamim Hafiz - MSFT
4
我同意这一点,在生产代码中永远不要使用*。你永远不知道以后是否会添加一些不应列出的列,例如出于安全原因。始终构建查询以仅获取所需的列。如果您想以动态方式执行此操作,请确保非常明显地将此注释给其他开发人员看。 - David Mårtensson
还有一点需要注意,如果使用SQL视图,在底层表发生更改(添加或删除列)时,视图会产生更多的副作用,因为视图不会自动更新,因此可能无法显示新列,或者现有列可能被替换,因为视图按照它们在创建视图时所拥有的索引来选取列。 - David Mårtensson
你会发现它们可能是按照那个顺序出现的(尽管我不确定SQL标准是否要求这样)。是的,SQL标准确实要求这样做。SQL-92规范,第7.9节(查询规范),第9b点:“如果选择列表中的第i个派生列没有指定as子句,并且该派生列的值表达式是单个列引用,则结果的第i列的列名为C。” - onedaywhen
此外,当使用 SELECT * 时,SQL-92 标准规定列按照它们在表中的序号升序引用。相关章节为4.8(列)和7.9(查询规范)。 - onedaywhen
@onedaywhen,这似乎支持了这样的观点:如果您想按特定顺序排列,则必须逐个列出列,是吗?否则,它将按序数位置输出,这可能是列在“create table”语句中的顺序。 - paxdiablo

4
  • 没有动态SQL,无法自动执行此操作。
  • 不建议使用SELECT *,也无法对列名进行排序。
  • 必须显式地执行SELECT age, name, sex FROM

在SQL层面上,这并不重要。这也不会影响任何客户端代码对象。

如果这很重要,那么在向客户端呈现数据时进行排序。

很抱歉,事情就是这样...


4
SQL-92标准规定,在使用SELECT *时,列按照它们在表中的序号升序引用。相关章节为4.8(列)和7.9(查询规范)。我不知道是否有任何供应商扩展标准,允许以任何其他顺序返回列,可能是因为通常不鼓励使用SELECT *
您可以使用SQL DDL确保列的序号与所需的字母顺序匹配。但是,仅当在FROM子句中引用单个表时,此方法才有效。如果引用了两个表,则SELECT *将按照序数位置顺序返回第一个表的列,然后是第二个表的列,因此完整结果集的列可能不是按字母顺序排列的。

2

如果你只是想在SQL Server中查找一个列

SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'MyTableThatCouldMaybeNeedNormalising'
order by COLUMN_NAME

0

您可以只指定要选择的列:

SELECT age, name, sex FROM Table

列将按照您在查询中指定的顺序显示。


非常感谢您的回答。实际情况是这样的,如果要写出这么多列会很繁琐。这就是为什么我想知道是否可以直接使用SQL查询来完成此操作的原因。也许另一种选择是将列名列出并使用外部程序对列名进行排序。 - Shamim Hafiz - MSFT

0
ORDER BY COLUMN_NAME ASC;

请注意,COLUMN_NAME函数用于引用表的列名。该函数并不适用于所有数据库系统,并且在某些情况下可能无法按预期工作。

欢迎来到SO!请先看一下之前已经给出的其他答案,你的方法可能已经被提及了。为了保持网站清晰易懂,方便查找答案,我们尽量避免重复回答。 - ahuemmer

0
另一种方法是通过使用SQL过程按字母顺序排列所有列来改变表格。我为一些用户喜欢字母布局的表格创建了这样的过程,同时仍然使用简化的SELECT *语句。
这段代码应该首先安排我的索引,然后按A-Z组织所有其他列。它可能与您的实例不同,但是作为一个很好的起点。
DELIMITER ;;

DROP PROCEDURE IF EXISTS ALPHABETISE_TABLE_COLUMNS;

CREATE PROCEDURE ALPHABETISE_TABLE_COLUMNS(IN database_name VARCHAR(64), IN table_name_string VARCHAR(64), IN index_name_string VARCHAR(64))

BEGIN

    DECLARE n INT DEFAULT 0;
    DECLARE i INT DEFAULT 0;
    DECLARE col_name VARCHAR(30) DEFAULT "";
    DECLARE col_datatype VARCHAR(10) DEFAULT "";
    DECLARE previous_col VARCHAR(30) DEFAULT col_name;

    SELECT COUNT(*) 
    FROM 
        (SELECT COLUMN_NAME 
        FROM INFORMATION_SCHEMA.COLUMNS 
        WHERE TABLE_NAME = table_name_string) AS TEMP 
    INTO n;

    SET @Q= CONCAT('ALTER TABLE `',database_name,'`.`',table_name_string,'` CHANGE COLUMN `',index_name_string,'` `',index_name_string,'` BIGINT(20) NOT NULL FIRST');
    PREPARE exe FROM @Q;
    EXECUTE exe;
    DEALLOCATE PREPARE exe;

    SET n = n-1;
    SET i=1;

    WHILE i<n DO 


        SELECT COLUMN_NAME FROM 
            (SELECT COLUMN_NAME, @row_num:= @row_num + 1 as ind_rows 
            FROM INFORMATION_SCHEMA.COLUMNS, (SELECT @row_num:= 0 AS num) AS c 
            WHERE TABLE_NAME = table_name_string AND COLUMN_NAME <> index_name_string 
            ORDER BY COLUMN_NAME ASC) as TEMP 
        WHERE ind_rows = i 
        INTO col_name;

        SELECT DATA_TYPE 
        FROM 
            (SELECT DATA_TYPE, @row_num:= @row_num + 1 as ind_rows 
            FROM INFORMATION_SCHEMA.COLUMNS, (SELECT @row_num:= 0 AS num) AS c 
            WHERE TABLE_NAME = table_name_string AND COLUMN_NAME <> index_name_string 
            ORDER BY COLUMN_NAME ASC) as TEMP 
        WHERE ind_rows = i 
        INTO col_datatype;

        IF i = 1 THEN
            SET previous_col = index_name_string;
        ELSE
            SELECT COLUMN_NAME 
            FROM 
                (SELECT COLUMN_NAME, @row_num:= @row_num + 1 as ind_rows 
                FROM INFORMATION_SCHEMA.COLUMNS, (SELECT @row_num:= 0 AS num) AS c 
                WHERE TABLE_NAME = table_name_string AND COLUMN_NAME <> index_name_string 
                ORDER BY COLUMN_NAME ASC) as TEMP 
            WHERE ind_rows = i-1
            INTO previous_col;
        END IF;

        IF col_datatype = 'varchar' THEN
            SET col_datatype = 'TEXT';
        END IF;

        select col_name, previous_col;
        IF col_name <> index_name_string OR index_name_string = '' THEN
            SET @Q= CONCAT('ALTER TABLE `',database_name,'`.`',table_name_string,'` CHANGE COLUMN `',col_name,'` `',col_name,'` ',col_datatype,' NULL DEFAULT NULL AFTER `',previous_col,'`');
            PREPARE exe FROM @Q;
            EXECUTE exe;
            DEALLOCATE PREPARE exe;
        END IF;
        SET i = i + 1;

    END WHILE;
END;
;;

DELIMITER ;

# NOTE: ASSUMES INDEX IS BIGINT(20), IF OTHER PLEASE ADAPT IN LINE 22 TO MEET DATATYPE
#
# CALL ALPHABETISE_TABLE_COLUMNS('database_name', 'column_name', 'index_name')


希望这对你有所帮助!

-2

是的。可以使用以下命令实现。

SELECT column_name FROM user_tab_cols WHERE table_name=UPPER('Your_Table_Name') order by column_name;

它将按字母顺序显示您表中的所有列。


无效的对象名称'user_tab_cols'。 - Billy Bob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接