そんなこと知ってる
SELECT * FROM Table
テーブル内のすべての列をリストしますが、列をアルファベット順にリストすることに興味があります。
たとえば、「名前」、「年齢」、「性別」の 3 つの列があるとします。
列を次の形式で整理したい
|age| |name| |sex|
SQLでこれを行うことは可能ですか?
そんなこと知ってる
SELECT * FROM Table
テーブル内のすべての列をリストしますが、列をアルファベット順にリストすることに興味があります。
たとえば、「名前」、「年齢」、「性別」の 3 つの列があるとします。
列を次の形式で整理したい
|age| |name| |sex|
SQLでこれを行うことは可能ですか?
これにより、select ステートメントですべての列がアルファベット順に並べられたクエリが生成されます。
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)
はいといいえ :-)
SQL 自体は、列がどの順序で表示されるかは気にしませんが、使用する場合は次のようになります。
select age, name, sex from ...
おそらくその順序で出てきたことがわかります(SQL標準でこれが義務付けられているかどうかはわかりませんが)。
今はやりたくないかもしれませんが、人生は公平ではない場合もあります :-)
また、DBMS データ定義テーブルを使用してクエリを動的に構築するという別の方法もあります。これは移植性がありませんが、ほとんどの DBMS がこれらのテーブル (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 は、可能な限り効率的な方法でデータを返すようにしておく必要があります。
SELECT *
は推奨されず、列名をソートしませんSELECT age, name, sex FROM
SQL レベルでは問題ありません。クライアントコードオブジェクトには関係ありません-
重要な場合は、クライアントにデータを提示するときに並べ替えます。
すみません、その通りです…
SQL-92標準では、列を使用SELECT *
する場合、テーブル内の順序位置の昇順で列が参照されるように指定されています。関連するセクションは、4.8(列)と7.9(クエリ仕様)です。おそらく使用SELECT *
が一般的に推奨されていないために、列を他の順序で返すことを可能にする標準のベンダー拡張機能を知りません。
SQL DDLを使用して、列の順序位置が目的のアルファベット順と一致するようにすることができます。ただし、これは、句で単一のテーブルを参照する場合にのみ、希望する方法で機能しますFROM
。2つのテーブルが参照SELECT *
されている場合、最初のテーブルの列が序数の順序で返され、次に2番目のテーブルの列が序数の順序で返されるため、結果セット全体の列がアルファベット順にならない場合があります。
選択したい列を指定するだけです:
SELECT age, name, sex FROM Table
列は、クエリで指定したのと同じ順序で表示されます。
別のアプローチは、SQL プロシージャーを介してテーブルを変更することにより、すべての列をアルファベット順に配置することです。ユーザーがアルファベット順のレイアウトを好み、簡略化されたSELECT *
ステートメントを使用しているいくつかのテーブル用に 1 つ作成しました。
このコードは、最初にインデックスを配置してから、AZ の他のすべての列を整理する必要があります。インスタンスによって異なる場合がありますが、出発点としては適切です。
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')
お役に立てれば!