SQLはSELECT * [列Aを除く] FROMテーブルAを使用して列を除外しますか?


733

テーブルからすべての列を選択するために、

SELECT * FROM tableA

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

SELECT * [except columnA] FROM tableA

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


27
この機能は、本番用のコードではなく、トラブルシューティングの目的で使用すると非常に便利です。例:クエリを実行する複数の列を含むテーブルがありますが、テキスト列をすばやく省略したいのですが。
ミカB.

openqueryを操作するときにこれが必要でした(ただし、SQL ServerではなくMySQLの機能が必要です)。SQL Serverを使用してMySQLデータベースにクエリを実行する必要がありました。MySQLテーブルには固定幅のchar列があったため、SELECT *クエリを使用できませんでした(OLE DBはそれらのマッピングに問題があります)。MySQLデータベースに直接アクセスできなかったため、正しい列を指定できませんでしたが、SQL Serverは、固定幅のchar列の名前を通知してくれました...
jahu

2
これを行う別の理由を追加したいと思いSELECT DISTINCT *ます。キー列が他の誰かが作成した重複行なしで機能することを除いて
undrline

1
時間のかかることに同意します。そのため、通常はテーブルを右クリックし、[上位1000行を選択]を選択して、不要な列を削除します。
ThomasRones

2
忘れないでください。多くの場合、列は変更される可能性があるため、開発者は列を知りません。これは、データウェアハウスでは一般的です。6か月後、追加の列が追加され、コードを変更せずに選択する必要があります。

回答:


447

私は皆に同意します...しかし、私がこのようなことをするつもりなら、私はこのようにするかもしれません:

/* 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

222
非効率的です...しかし非常に創造的です:)
GuillermoGutiérrez

1
綺麗な。2つの一時テーブルまたは別のテーブルへの一時を結合する必要があることがよくあります。特に、グループ化が含まれるため、一時にすべての列が必要なわけではありません。
VISQL

2
非常に素晴らしい。確かに列名を抽象化する問題を解決します。
トースター、

1
@CeesTimmerman-重複する列名を含むクエリがある場合、それは別の問題であり、どのアプローチを採用しているかに関係なく。Googleの「SQL column rename」または「SQL column alias」。SELECT table1.ID AS table1ID ...IIRCのようなもの。
ToolmakerSteve 2014

3
@ToolmakerSteveこの質問のアイデアは、不要な列のみを指定することです。列に名前を付けるには、たとえば特定のテーブルの20以上の列をすべて指定する必要があります。
Cees Timmerman、2014

289

番号。

保守が容易なベストプラクティスは、必要な列のみを指定することです。

少なくとも2つの理由:

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

編集(2011年7月):

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


3
列をドラッグすることについて私は決して知りませんでしたGBN、あなたが再びその日を救ったことに感謝します。SQLの専門知識があるため、$$をたくさん稼ぐ必要があります
l --''''''--------- '' '' '' '' '' ''

4
特にETLルーチンでは、SELECT *を使用した有効なシナリオがあります。ここでの最良の答えは、動的SQLの答えだと思います。
ミシキン14

1
統計的調査のために学生のすべてのデータを言うが、プライバシーを強化するために学生ID自体を引き出さないようにしたい場合があります
George Birbilis 14

3
「必要な列のみを指定」-ハードコーディングノンセンス
RMヘイリー

9
このような答えは多くの票を獲得しますが、私に関する限り、それらは価値がありません。概念的には、「選択* ABC以外」を選択できることは、言語がサポートする「選択*」よりも問題になりません。OPは明らかに何かを達成する方法を求めています。この質問に答える人は、OPがこれを本番用コードで使用したいのか、またはデータベース用のコードを開発しているときにすぐにこのようなクエリを実行する必要があるのか​​を知る方法がないため、優れた標準についての講義まったく価値がありません。
itsme2003

68

各列名を手動で記述したくない場合は、次のようにSSMSScript Table Asテーブルまたはビューを右クリックして使用できます。

ここに画像の説明を入力してください

次に、新しいクエリエディターウィンドウで選択クエリ全体を取得し次のように不要な列を削除します。

ここに画像の説明を入力してください

できた


2
これは、すべての列名を選択してからカンマを追加するよりも簡単です。
shaijut 16

68

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);

CTEまたはその他のサブクエリの結果からクエリを実行している場合はどうなりますか?簡単な例:row_number()各行に結果を追加するサブクエリを作成し、によって結合を実行し、結合の結果からを除くrow_numberすべてrow_number選択する場合があります。
2016年

43

選択したい列を含むビューを作成し、select *そのビューから...


8
最初の私の反応は、「列を指定するよりも、これはどのように簡単なのですか」でした。しかし、メンテナンスの観点からは、改善になる可能性があると判断しました。
ToolmakerSteve 2014

1
これは、一時テーブルや動的SQLでクエリオプティマイザーを打ち消すのではなく、クエリオプティマイザーもサポートします。
underscore_d 2016年

30

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

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. 動的SQLEXEC (@variable)とも呼ばれるを使用して、実行時に列名を解決します。これは、コンパイル時に列名がわからないために必要です。

ありがとう!これが私の問題を解決する鍵でした。
アントニオ

質問が1つあります。どのような理由で、2番目の選択をEXECステートメントに入れる必要があるのですか。私はそれが効果的に必要であることを見てきましたが、なぜ私は単純に書くことができないのだろうと思いますSELECT @columns FROM contact
Antonio

17

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

select top 1 * from table

そして、出力ウィンドウから列のリスト全体を切り取ります。次に、すべてを入力しなくても、必要な列を選択できます。


13
SSMSからのドラッグに関する私のヒントを参照してください
gbn

11

基本的に、あなたが望むことを行うことはできません-しかし、物事を少し簡単にするのに役立つ適切なツールを手に入れることができます。

Red-GateのSQLプロンプトを見ると、「SELECT * FROM MyTable」と入力し、カーソルを「*」の後ろに戻し、<TAB>を押してフィールドのリストを展開し、いくつかのフィールドを削除します。必要ありません。

それは完璧な解決策ではありません-しかし、とても良い解決策です!:-) MS SQL Server Management StudioのIntellisenseは残念ながら、この機能を提供するのに十分なほどインテリジェントではありません。

マーク


これは良いことですが、問題はクエリが巨大になる可能性があることです。製品コードではなく、アドホッククエリ用の「except」機能があると便利です。
ミカB.

8

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

編集 DBが動的SQLの実行をサポートしている場合、uはSPを作成し、表示したくない列を渡してクエリを動的に作成し、結果を返すことができます。これはSQL Serverで少なくとも実行可能だと思います


13
それは可能ですが、私はそれをしている人を解雇します。
Lieven Keersmaekers、2009

古典的なクリーンアップの問題:保持したいdfataを一時テーブルにコピーし、大きなデータを切り捨てて、一時テーブルで再入力します。ID列を除外する必要があります。
Volker

8

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

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

楽しい。


7

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


6

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


結合を行うときに、「SELECT table1。* ...」のように、「innername。*」のバリエーションを使用して内部列を表すことができますか?
ToolmakerSteve 2014

6
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';

5

プロシージャの場合は、このトリックを使用して新しいクエリを生成し、即時実行します。

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

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

通常の方法で宣言型SQLを使用します。

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

ただし、SQLはSELECT *すでにかなりの問題を抱えているため(@Guffaの回答はここでの典型的な異論です)、SELECT ALL BUTすぐにSQL標準に入るとは思いません。

私が一番の「回避策」はVIEW、あなたが望む列だけでを作成することだと思いますSELECT * FROM ThatView


1
@underscore_d:回答を修正しました。
onedaywhen

クール、最後の2つの段落に同意します。チュートリアルDに関する情報は興味深いですが、select *疑わしいと思う人たちに同意する傾向があります-データテーブルを一般的に処理する必要があるアドホックなものやプログラムには非常に役立ちますが、構築にはそれほど役立ちません(より適切な言葉がないため)。 「純粋な」クエリ。それでも、ANSI標準に含まれていなくても、他の多くのものと同様に、Microsoftが方言にそれを追加できないわけではありませんが、そうするかどうかは疑問です。
underscore_d 2016年

5

BigQueryのような最新のSQL方言は優れたソリューションを提案します

SELECT * EXCEPT(ColumnNameX、[ColumnNameY、...])

これは非常に強力なSQL構文であり、テーブルの列名の変更により常に更新する必要がある列の長いリストを回避します。そして、この機能は残念なことに現在のSQL Serverの実装にはありません。うまくいけば、いつかMicrosoft Azureがデータサイエンティストにもっと友好的になるでしょう。

データサイエンティストは、クエリを短縮し、一部の列を削除できる(重複またはその他の理由により)迅速なオプションを使用できるようにしたいと考えています。

https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#select-modifiers


4

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 FROM officepark As o


これは理論的には質問に答える可能性がありますが、答えの本質的な部分をここに含め、参照用のリンクを提供することが望ましいでしょう
Bhargav Rao

3

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

もちろん、SQLステートメントを動的に作成して、サーバーに実行させることもできます。しかし、これによりSQLインジェクションの可能性が広がります。


3

これは少し古いことを知っていますが、同じ問題に遭遇して答えを探していました。次に、上級開発者に非常に簡単なトリックを見せてもらいました。

Management Studioクエリエディターを使用している場合は、データベースを展開してから、選択元のテーブルを展開すると、列フォルダーが表示されます。

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


1
はい、しかし、もしあなたが5つの参加を持っているなら、アイデアはそうするでしょうSELECT * Except(tableName.ColumnName) FROM ...
Pawel Cioch

私はこれが便利だと思います:)それについては知りませんが、それでもトピックの質問に対する答えではありません。
Fka 2015

3

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

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)

3
列の数が多い場合、たとえば100とすると、1つを除くすべての列をSELECTしたいとします。より良いアプローチはありますか?
KartikKannapur 2016年

5
これは一種の要点を逃しています。2番目の呼び出しで「id、date」を選択しています。これを行う場合は、最初にそれを実行してください。
keithpjolley 2017年

3

たとえば、パスワードのように大文字と小文字を区別する列を除外する場合は、次のようにして値を非表示にします。

SELECT * , "" as password FROM tableName;


これは私のために働きました
Arun Prasad ES

1
もちろん、クリアテキストのパスワードをデータベースに保存しないでください。少なくともそれらはソルトでハッシュし、多分ペッパーsecurity.stackexchange.com/questions/3272/…
Anders_K

2

まあ、単に*を指定するのではなく、必要な列を指定することが一般的なベストプラクティスです。したがって、selectが返すフィールドを指定するだけです。


2

同僚は良い代替案をアドバイスしました:

  • 前のクエリ(データを生成または取得する場所)でSELECT INTOを実行して、テーブル(完了時に削除します)に入れます。これにより、構造が作成されます。
  • 新しいクエリウィンドウに対してCREATEとしてスクリプトを実行します。
  • 不要な列を削除します。残りの列を1ライナーにフォーマットし、列リストとして貼り付けます。
  • 作成したテーブルを削除します。

完了...

これは私たちに大いに役立ちました。


1

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

*ではなく、すべての列がリストされます。次に、不要な列を削除します。自分で入力するよりもはるかに速いはずです。

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


1

このケースで私がよく使用するのは次のとおりです。

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)

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


1

同じプログラムが異なるデータベース構造を処理する必要がある場合があります。そのため、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

質問/問題を詳しく説明/明確化することを検討してください。
badfilms

1

私はこの質問が古いことを知っていますが、これがまだ役立つことを願っています。回答は、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

これを行う方が簡単ではありませんか?

sp_help <table_name>

-[Column_name]列をクリックし、[コピー]> [貼り付け](垂直リストを作成)を[新しいクエリ]ウィンドウに挿入し、各列の値の前にカンマを入力するだけです...不要な列をコメントにしてください...ここで提供されているどのコードよりもタイピングしやすく、まだ管理可能です。


「ここに提供されているどのコードよりも入力がはるかに少なく」、「列」ノードをクエリエディターにドラッグしたり、リストを取得する他の優れた方法よりもはるかに手間がかかりません。何十列もの列を持つテーブルはどうですか?
underscore_d 2016年

0

SQL Completeはdevart.comから入手できます。これは、Red GateからのSQLプロンプトのように*ワイルドカードを拡張するだけでなく(cairnzの回答で説明)、列ピッカードロップダウンにチェックボックスがあり、すべてをチェックできます。選択リストに追加したい列が自動的に挿入されます(列をオフにすると、選択リストから自動的に削除されます)。


0

SSMSでは、IntelliSenseエイリアス使用する簡単な方法がありますます。これを試して

  1. テキストエディターを右クリックして、 IntelliSenseが有効になっます
  2. エイリアスを使用してクエリを入力します[SELECT t。* FROM tablename t]を。
  3. テキスト移動します*。トンを、削除*を列、およびSSMS意志の自動リストFをエイリアステーブルを。
次に、 SSMSを使用して別のスクリプトに選択を書き込んでから、コピー/貼り付け操作を実行する必要がない列のみをすばやく指定できます。いつも使っています。


列の除外に対する回答を指定していただけますか?
Kamiccolo 2014年

@Kamiccolo-DuckWorkによって記述されているのは手動アクションです。目的の列名を切り取って貼り付けます。彼は、これは多くの入力をせずに名前をより簡単に取得する方法であると単に言っています。「この列を除外する」というクエリの記述には役立ちません。必要な列のリストを作成し、それをクエリに貼り付けるだけです。
ToolmakerSteve 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.