web-dev-qa-db-ja.com

SQLはSELECT * [except columnA] FROM tableAを使用して列を除外しますか?

テーブルからすべての列を選択するには、次のようにします。

SELECT * FROM tableA

すべての列を指定せずにテーブルから列を除外する方法はありますか?

SELECT * [except columnA] FROM tableA

私が知っている唯一の方法は、手動ですべての列を指定し、不要な列を除外することです。これは本当に時間がかかるので、私はこれに時間と労力を節約する方法を探しています、そしてテーブルがより多くの/より少ない列を持っているなら将来のメンテナンスと同様に。

ありがとうございます。

612
uuɐɯǝʃǝs

私はみんなに同意します...しかし、もし私がこのようなことをやろうとしていたら私はそれをこうするかもしれません:

/* Get the data into a temp table */
SELECT * INTO #TempTable
FROM YourTable
/* Drop the columns that are not needed */
ALTER TABLE #TempTable
DROP COLUMN ColumnToDrop
/* Get results and drop temp table */
SELECT * FROM #TempTable
DROP TABLE #TempTable
395
Norman Skinner

いいえ.

メンテナンスライトのベストプラクティスは、必要な列だけを指定することです。

少なくとも2つの理由:

  • これにより、クライアントとデータベース間の契約が安定します。毎回同じデータ
  • パフォーマンス、インデックスをカバー

編集(2011年7月):

オブジェクトエクスプローラからテーブルのColumnsノードをドラッグすると、クエリウィンドウにCSVの列リストが表示され、目的の1つを達成できます

273
gbn

SQL(SQL Server)でこれを自動化する方法は、次のとおりです。

declare @cols varchar(max), @query varchar(max);
SELECT  @cols = STUFF
    (
        ( 
            SELECT DISTINCT '], [' + name
            FROM sys.columns
            where object_id = (
                select top 1 object_id from sys.objects
                where name = 'MyTable'
            )
            and name not in ('ColumnIDontWant1', 'ColumnIDontWant2')
            FOR XML PATH('')
        ), 1, 2, ''
    ) + ']';

SELECT @query = 'select ' + @cols + ' from MyTable';  
EXEC (@query);
62
pl80

手動で各カラム名を書きたくない場合は、 table または view in _ ssms _ を右クリックしてScript Table Asを使用できます。

enter image description here

その後、 新しいクエリエディタウィンドウ に選択クエリ全体が表示されます。その後、次のように不要な列を削除します。

enter image description here

完了

57
hims056

あなたが選択したい列を持つビューを作成することができます、そしてあなたはただビューから*を選択することができます...

35
campo

はい、可能です(しかしお勧めできません)。

CREATE TABLE contact (contactid int, name varchar(100), dob datetime)
INSERT INTO contact SELECT 1, 'Joe', '1974-01-01'

DECLARE @columns varchar(8000)

SELECT @columns = ISNULL(@columns + ', ','') + QUOTENAME(column_name)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'contact' AND COLUMN_NAME <> 'dob'
ORDER BY ORDINAL_POSITION

EXEC ('SELECT ' + @columns + ' FROM contact')

コードの説明

  1. 列名のコンマ区切りリストを格納するための変数を宣言します。デフォルトはNULLです。
  2. システムビューを使用して、テーブル内の列の名前を特定します。
  3. 列名を連結するにはSELECT @variable = @variable + ... FROMを使用してください。このタイプのSELECTは結果セットを返しません。これはおそらく文書化されていない動作ですが、SQL Serverのすべてのバージョンで機能します。代わりに、SET @variable = (SELECT ... FOR XML PATH(''))を使って文字列を連結することもできます。
  4. 最初の列名ではない場合にのみ、ISNULL関数を使用してコンマを追加します。列名のスペースと句読点をサポートするには、QUOTENAME関数を使用します。
  5. 表示したくない列を非表示にするにはWHERE句を使用します。
  6. 実行時に列名を解決するには、EXEC (@variable) 動的SQL とも呼ばれる)を使用します。コンパイル時に列名がわからないため、これが必要です。
23
Anthony Faull

他の人がこれを行う方法はないと言っているように、Sql Serverを使用している場合、私が使用するトリックは、出力をカンマ区切りに変更することです。

select top 1 * from table

出力ウィンドウから列のリスト全体を切り取ります。それからそれらをすべてタイプする必要なしであなたがほしいと思うどのコラムを選ぶことができる。

17
MrTelly

基本的に、あなたはあなたが望むことをすることができません - しかし、あなたは物事をもう少し簡単にするのを手助けするために正しいツールを手に入れることができます。

Red-Gateの SQLプロンプト を見れば、 "SELECT * FROM MyTable"と入力して、カーソルを "*"の後ろに戻し、<TAB>を押してフィールドのリストを展開し、削除することができます。あなたが必要としないそれらの少数の分野。

それは完璧な解決策ではありません - しかし気の利いた解決策! MS SQL Server Management StudioのIntellisenseは、この機能を提供するにはまだインテリジェントではありません。

マーク

11
marc_s

SQL Management Studioでは、オブジェクトエクスプローラで列を展開してからColumnsツリー項目をクエリウィンドウにドラッグして、カンマ区切りの列リストを取得できます。

7
cjk

いいえこれを行う方法はありません。状況に応じてカスタムビューを作成することもできます。

_ edit _ あなたのDBが動的SQLの実行をサポートしているのであれば、SPを書いてカラムを渡すことができるでしょう。結果はあなたに。私はこれが少なくともSQL Serverで実行可能であると思います

7
Ali Kazmi

SQL Server Management Studioを使用している場合は、次のようにします。

  1. 希望のテーブル名を入力して選択します
  2. 押す Alt+F1
  3. o/pはテーブル内の列を示します。
  4. 希望の列を選択
  5. 選択クエリにそれらをコピーして貼り付けます
  6. クエリを起動します。

楽しい。

7
asdasdasd
DECLARE @SQL VARCHAR(max), @TableName sysname = 'YourTableName'

SELECT @SQL = COALESCE(@SQL + ', ', '') + Name 
FROM sys.columns
WHERE OBJECT_ID = OBJECT_ID(@TableName)
AND name NOT IN ('Not This', 'Or that');

SELECT @SQL = 'SELECT ' + @SQL + ' FROM ' + @TableName

EXEC (@SQL)

更新:

頻繁に使用する場合は、このタスクを処理するストアドプロシージャを作成することもできます。この例では、SQL Server 2016以降で利用可能な組み込みの STRING_SPLIT() を使用しましたが、必要に応じてSOで手動で作成する方法の例が多数あります。

CREATE PROCEDURE [usp_select_without]
@schema_name sysname = N'dbo',
@table_name sysname,
@list_of_columns_excluded nvarchar(max),
@separator nchar(1) = N','
AS
BEGIN
 DECLARE 
 @SQL nvarchar(max),
 @full_table_name nvarchar(max) = CONCAT(@schema_name, N'.', @table_name);

 SELECT @SQL = COALESCE(@SQL + ', ', '') + QUOTENAME([Name])
 FROM sys.columns sc
 LEFT JOIN STRING_SPLIT(@list_of_columns_excluded, @separator) ss ON sc.[name] = ss.[value]
 WHERE sc.OBJECT_ID = OBJECT_ID(@full_table_name, N'u')
 AND ss.[value] IS NULL;

 SELECT @SQL = N'SELECT ' + @SQL + N' FROM ' + @full_table_name;
 EXEC(@SQL)
END

そしてそれだけで:

EXEC [usp_select_without] 
@table_name = N'Test_Table',
@list_of_columns_excluded = N'ID, Date, Name';
6
Bartosz X

要約するとできませんが、上記のすべてのコメントには同意できません。リスト全体から特定の範囲を選択するためにネストされたクエリを作成する場合など、合法的に使用できるシナリオがあります。ページング)なぜあなたは内側でそれをやったときに、なぜ世界で外側のselect文の各列を指定したいと思うでしょうか?

6
Useless Hasid

すべての列を指定せずにテーブルから列を除外する方法はありますか?

通常の方法で宣言型SQLを使用する、いや。

あなたが提案した構文は価値があり、良いと思います。実際、リレーショナルデータベースの言語「チュートリアルD」は、キーワードALL BUTの後に一連の属性(列)が続くという非常によく似た構文を持っています。

しかし、SQLのSELECT *はすでに多くの弱点があるので(@ Guffaの回答は一般的な反対意見です)、SELECT ALL BUTが間もなくSQL標準に入るとは思わない。

最善の「回避策」は、あなたが望むカラムだけでSELECT * FROM ThatViewを持つVIEWを作成することだと私は思います。

5
onedaywhen

手続きについて話しているのであれば、このトリックと連携して新しいクエリを生成し、 EXECUTE IMMEDIATE it:

SELECT LISTAGG((column_name), ', ') WITHIN GROUP (ORDER BY column_id)
INTO var_list_of_columns
FROM ALL_TAB_COLUMNS
WHERE table_name = 'PUT_HERE_YOUR_TABLE'
AND column_name NOT IN ('dont_want_this_column','neither_this_one','etc_column');
5
AlexandreWL

私はこれをサポートするデータベース(SQL Server、MySQL、Oracle、PostgreSQL)を知りません。これは間違いなくSQL標準の一部ではないので、私はあなたが望むカラムだけを指定する必要があると思います。

もちろん、SQL文を動的に構築してサーバーに実行させることもできます。しかしこれはSQLインジェクションの可能性を切り開きます。

3

私はこれが少し古いことを知っています、しかし私はちょうど同じ問題に遭遇したところで、そして答えを探していました。それから私は上級開発者に私に非常に単純なトリックを見せてもらいました。

Management Studioのクエリーエディタを使用している場合は、データベースを展開し、次に選択しているテーブルを展開して、columnsフォルダを表示できるようにします。

Selectステートメントで、上の参照先の列フォルダーをハイライトして、それをクエリウィンドウにドラッグアンドドロップするだけです。それはテーブルのすべての列を貼り付けます、そして単に列のリストから単にID列を削除します...

3
anonymous

PostgresのSQLはそれを行う方法があります

plsは参照: http://www.postgresonline.com/journal/archives/41-How-to-SELECT-ALL-EXCEPT-some-columns-in-a-table.html

情報スキーマハックウェイ

SELECT 'SELECT ' || array_to_string(ARRAY(SELECT 'o' || '.' || c.column_name
        FROM information_schema.columns As c
            WHERE table_name = 'officepark' 
            AND  c.column_name NOT IN('officeparkid', 'contractor')
    ), ',') || ' FROM officepark As o' As sqlstmt

私の特定の例のテーブルのための上記 - このようなSQLステートメントを生成します

SELECT o.officepark、o.owner、o.squarefootage officeparkからo

2
user3393089

これを解決する最善の方法は、ビューを使用することです。必要な列でビューを作成し、それからデータを取得することができます。

example

mysql> SELECT * FROM calls;
+----+------------+---------+
| id | date       | user_id |
+----+------------+---------+
|  1 | 2016-06-22 |       1 |
|  2 | 2016-06-22 |    NULL |
|  3 | 2016-06-22 |    NULL |
|  4 | 2016-06-23 |       2 |
|  5 | 2016-06-23 |       1 |
|  6 | 2016-06-23 |       1 |
|  7 | 2016-06-23 |    NULL |
+----+------------+---------+
7 rows in set (0.06 sec)

mysql> CREATE VIEW C_VIEW AS
    ->     SELECT id,date from calls;
Query OK, 0 rows affected (0.20 sec)

mysql> select * from C_VIEW;
+----+------------+
| id | date       |
+----+------------+
|  1 | 2016-06-22 |
|  2 | 2016-06-22 |
|  3 | 2016-06-22 |
|  4 | 2016-06-23 |
|  5 | 2016-06-23 |
|  6 | 2016-06-23 |
|  7 | 2016-06-23 |
+----+------------+
7 rows in set (0.00 sec)
2

まあ、*を指定するのではなく、どのカラムを使用するのかを指定するのが一般的なベストプラクティスです。それで、あなたはあなたがあなたにあなたが選択に返させたいフィールドを単に述べるべきです。

2
Gustavo

大学は良い代替案を勧めました:

  • 前のクエリ(データの生成元または取得先)でSELECT INTOを実行してテーブルにします(実行後に削除します)。これはあなたのための構造を作成します。
  • 新しいクエリウィンドウに対してCREATEとしてスクリプトを実行します。
  • 不要な列を削除してください。残りの列を1行にフォーマットして、列リストとして貼り付けます。
  • 作成したテーブルを削除します。

完了しました...

これは私達を大いに助けました。

2
Charl

同じプログラムが異なるデータベース構造を処理しなければならない場合があります。そのため、selectステートメントのエラーを回避するためにプログラムで列リストを使用することはできませんでした。

*は私にすべてのオプションのフィールドを与えます。使用前にデータテーブルにフィールドが存在するかどうかを確認します。これがselect*を使用する理由です。

これは私が除外されたフィールドを処理する方法です:

Dim da As New SqlDataAdapter("select * from table", cn)
da.FillSchema(dt, SchemaType.Source)
Dim fieldlist As String = ""
For Each DC As DataColumn In DT.Columns
   If DC.ColumnName.ToLower <> excludefield Then
    fieldlist = fieldlist &  DC.Columnname & ","
   End If
  Next
1
Dusan

私がこのケースでよく使うのは、

declare @colnames varchar(max)=''

select @colnames=@colnames+','+name from syscolumns where object_id(tablename)=id and name not in (column3,column4)

SET @colnames=RIGHT(@colnames,LEN(@colnames)-1)

@colnamescolumn1,column2,column5のように見えます

1
Valeriy

オブジェクトエクスプローラでテーブルを右クリックし、上位1000行を選択

*ではなく、すべての列が一覧表示されます。その後、不要な列を削除してください。自分で入力するよりもはるかに速いはずです。

次に、これが少しやり過ぎだと感じたら、Red GateのSQLプロンプトを表示し、tblからssfと入力し、*に移動してもう一度タブをクリックします。

1
cairnz

実際のテーブルの代わりにビューを使用しているときにBartoszXから提案された回答(ストアドプロシージャ)がうまく機能しませんでした。

このアイデアと以下のコードの功績は(私の修正を除いて)BartoszXに属します。

これがビューだけでなくテーブルにも機能するようにするには、次のコードを使用します。

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[select_without]
@schema_name sysname = N'dbo',
@table_name sysname,
@list_of_columns_excluded nvarchar(max),
@separator nchar(1) = N','
AS
BEGIN
 DECLARE 
 @SQL nvarchar(max),
 @full_table_name nvarchar(max) = CONCAT(@schema_name, N'.', @table_name);

 SELECT @SQL = COALESCE(@SQL + ', ', '') + QUOTENAME([Name])
 FROM sys.columns sc
 LEFT JOIN STRING_SPLIT(@list_of_columns_excluded, @separator) ss ON sc.[name] = ss.[value]
 WHERE sc.OBJECT_ID = OBJECT_ID(@full_table_name)
 AND ss.[value] IS NULL;

 SELECT @SQL = N'SELECT ' + @SQL + N' FROM ' + @full_table_name;
 EXEC(@SQL)
END
GO
0
Michael Hafner

これを行う方が簡単ではないでしょうか。

sp_help <table_name>

- [列名]列をクリックし、[コピー]> [貼り付け](縦のリストを作成)の順にクリックし、各列の値の前にカンマを入力します。不要な列はコメントアウトします。ここで提供されているコードよりもタイピングしていて、まだ管理可能です。

0
plo

私はこの質問が古くなっていることを知っていますが、これがまだ役に立つことを願っています。答えは SQL Serverフォーラム からの議論に触発されています。これを ストアード・プロシージャー にすることができます。フィールド以外に複数を追加するように変更することもできます。

DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = COALESCE(@SQL + ', ', ' ' ) + name from sys.columns where name not in ('colName1','colName2') and object_id = (Select id from sysobjects where name = 'tblName')
SELECT @SQL = 'SELECT ' + @SQL + ' FROM ' + 'tblName'
EXEC sp_executesql  @SQL
0
Weihui Guo

Devart.comからSQL Completeを入手することができます。これは、Red GateからのSQLプロンプトのように*ワイルドカードを展開するだけでなく(cairnzの回答で説明されているように)選択リストに必要な列は自動的に挿入されます(その後、列のチェックマークを外すと自動的に選択リストから削除されます)。

0
yoel halb

これはデータベースからロードする時間を節約しません。しかし、それが配置されている配列内の不要な列をいつでも設定解除することができます。テーブル内に複数の列がありましたが、特定のものは必要ありませんでした。 SELECTステートメントにそれらをすべて書き出すのは怠惰でした。

$i=0;
$row_array = array();

while($row = mysqli_fetch_assoc($result)){

  $row_array[$i]=$row;
  unset($row_array[$i]['col_name']);
  $i++;
}
0
user3904583

私はこのようにしました、そしてそれはちょうどうまく動きます(バージョン5.5.41):

# prepare column list using info from a table of choice
SET @dyn_colums = (SELECT REPLACE(
GROUP_CONCAT(`COLUMN_NAME`), ',column_name_to_remove','') 
FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE 
`TABLE_SCHEMA`='database_name' AND `TABLE_NAME`='table_name');

# set sql command using prepared columns
SET @sql = CONCAT("SELECT ", @dyn_colums, " FROM table_name");

# prepare and execute
PREPARE statement FROM @sql;
EXECUTE statement;
0

私がこれを使っていたように、ここの誰かがMySqlを使っているなら:

CREATE TABLE TempTable AS SELECT * FROM #YourTable; 

ALTER TABLE TempTable 
DROP COLUMN #YourColumn; 

SELECT * FROM TempTable; 
DROP TABLE TempTable;
0
Felix