SQL excluir uma coluna usando SELECT * [exceto columnA] FROM tableA?


733

Todos sabemos que para selecionar todas as colunas de uma tabela, podemos usar

SELECT * FROM tableA

Existe uma maneira de excluir colunas de uma tabela sem especificar todas as colunas?

SELECT * [except columnA] FROM tableA

A única maneira que eu sei é especificar manualmente todas as colunas e excluir a coluna indesejada. Isso consome muito tempo, então estou procurando maneiras de economizar tempo e esforço nisso, bem como manutenção futura, caso a tabela tenha mais / menos colunas.


27
Seria muito conveniente ter esse recurso, não para inserir código de produção, mas para fins de solução de problemas. Exemplo: eu tenho uma tabela que possui várias colunas que consulta, mas quero omitir rapidamente uma ou duas colunas de texto.
Micah B.

Eu precisava disso quando trabalhava com o openquery (embora eu precise da funcionalidade no MySQL e não no SQL Server). Eu tive que consultar um banco de dados MySQL usando o SQL Server. Como uma tabela MySQL tinha colunas de caracteres de largura fixa, eu não poderia usar uma SELECT *consulta (o OLE DB tem problemas para mapear essas). Não pude especificar as colunas corretas porque não tinha acesso direto ao banco de dados MySQL, no entanto, o SQL Server teve a gentileza de me informar os nomes das colunas char de largura fixa ...
jahu

2
Gostaria de adicionar outro motivo para fazer isso: SELECT DISTINCT *exceto para a coluna-chave funcionar sem linhas duplicadas que alguém mais criou
sublinhe

1
Eu concordo que é demorado. É por isso que geralmente clico com o botão direito do mouse na tabela, escolha "selecione as 1000 principais linhas" e removo as colunas que não desejo.
ThomasRones

2
a não esquecer: em muitos casos, o desenvolvedor não conhece as colunas porque elas podem mudar. isso é típico em data warehouses. após 6 meses, eles adicionam uma coluna adicional e deve ser selecionada sem alterar o código.

Respostas:


447

Eu concordo com todos ... mas se eu fosse fazer algo assim, poderia fazê-lo desta maneira:

/* 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
Ineficiente ... mas muito :) criativo
Guillermo Gutiérrez

1
Bonita. Geralmente, preciso incluir a junção de duas tabelas temporárias ou uma temporária a outra tabela em que não preciso de todas as colunas da temp - especialmente porque o agrupamento estará envolvido.
VISQL

2
Muito agradável. Claro resolve o problema de abstrair os nomes das colunas.
Torradeira

1
@ CeesTimmerman - se você tiver uma consulta envolvendo nomes de colunas duplicados, esse é um problema separado, independentemente da abordagem adotada. Google "renomear coluna SQL" ou "alias da coluna SQL". Algo como SELECT table1.ID AS table1ID ..., IIRC.
Home

3
@ToolmakerSteve A idéia desta pergunta é especificar apenas as colunas que você não precisa. A nomeação de colunas exigiria a especificação de todas, digamos, mais de 20 colunas de uma tabela específica.
precisa saber é o seguinte

289

Não.

A prática recomendada da luz de manutenção é especificar apenas as colunas necessárias.

Pelo menos 2 razões:

  • Isso torna seu contrato entre cliente e banco de dados estável. Os mesmos dados, sempre
  • Desempenho, cobrindo índices

Editar (julho de 2011):

Se você arrastar do Columnsnó do Pesquisador de objetos para uma tabela, ele colocará uma lista CSV de colunas na janela de consulta para você, que alcançará uma de suas metas


3
eu nunca soube o que é arrastar a coluna, obrigado GBN, você salvou o dia novamente. você deve fazer um monte de $$ devido à sua experiência em sql
l --''''''--------- '' '' '' '' '' ''

4
existem cenários válidos com SELECT *, especialmente em rotinas ETL. Eu acho que a melhor resposta aqui é aquela com SQL dinâmico.
Mishkin

1
Há casos em que você deseja selecionar dizer todos os dados para um estudante para a exploração estatística, mas não derrubar o fio da própria carteira de estudante para reforçar a privacidade
George Birbilis

3
"especifique apenas as colunas necessárias" - nonsence de codificação codificada
RM Haley

9
Embora respostas como essa recebam muitos votos, elas não têm valor para mim. Conceitualmente, ser capaz de "Selecionar * Exceto ABC" não é mais problemático que "Selecionar *", compatível com o idioma. O OP está claramente pedindo uma maneira de realizar alguma coisa. A pessoa que responde a essa pergunta não tem como saber se o OP deseja usar isso no código de produção ou se apenas tem uma necessidade imediata de executar uma consulta como essa enquanto está desenvolvendo algum código para o banco de dados, portanto, a palestra sobre bons padrões não contribui com nenhum valor.
Itsme2003

68

Se você não quer escrever o nome de cada coluna manualmente, você pode usar Script Table Aso botão direito sobre a tabela ou vista em SSMS como este:

insira a descrição da imagem aqui

Em seguida, você receberá toda a consulta de seleção na janela do novo editor de consultas e removerá a coluna indesejada como esta:

insira a descrição da imagem aqui

Feito


2
É mais fácil do que selecionar todos os nomes de colunas e adicionar vírgulas.
shaijut 12/12/16

68

A maneira automatizada de fazer isso no 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);

E se você estiver consultando o resultado de uma CTE ou outra subconsulta? Um exemplo simples: convém criar uma subconsulta que acrescente o resultado row_number()a cada linha, depois realizar uma junção row_numbere selecionar tudo, excetorow_number o resultado da junção.
Ely

43

Você pode criar uma exibição com as colunas que deseja selecionar e, a select *partir da exibição, pode ...


8
No começo, minha reação foi "como isso é mais fácil do que apenas especificar as colunas"? Mas então decidi que, do ponto de vista da manutenção, poderia ser uma melhoria.
Home

1
Isso também suporta o otimizador de consultas, em vez de neutralizá-lo com uma tabela temporária ou SQL dinâmico.
underscore_d

30

Sim, é possível (mas não recomendado).

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

Explicação do código :

  1. Declare uma variável para armazenar uma lista separada por vírgula de nomes de colunas. O padrão é NULL.
  2. Use uma visualização do sistema para determinar os nomes das colunas em nossa tabela.
  3. Use SELECT @variable = @variable + ... FROMpara concatenar os nomes das colunas. Esse tipo de SELECTnão retorna um conjunto de resultados. Talvez esse seja um comportamento não documentado, mas funciona em todas as versões do SQL Server. Como alternativa, você pode usar SET @variable = (SELECT ... FOR XML PATH(''))para concatenar seqüências de caracteres.
  4. Use a ISNULLfunção para acrescentar uma vírgula apenas se este não for o primeiro nome da coluna. Use a QUOTENAMEfunção para suportar espaços e pontuação nos nomes das colunas.
  5. Use a WHEREcláusula para ocultar colunas que não queremos ver.
  6. Use EXEC (@variable), também conhecido como SQL dinâmico , para resolver os nomes das colunas em tempo de execução. Isso é necessário porque não sabemos os nomes das colunas no momento da compilação.

Obrigado! Essa foi a chave para resolver meu problema .
Antonio

Eu tenho uma pergunta: por qual motivo a segunda seleção deve ser colocada em uma instrução EXEC? Eu vi que é efetivamente necessário, mas eu me pergunto por que não pode simplesmente escreverSELECT @columns FROM contact
Antonio

17

Como os outros disseram, não há como fazer isso, mas se você estiver usando o Sql Server, um truque que eu uso é alterar a saída para separada por vírgula.

select top 1 * from table

e recorte toda a lista de colunas da janela de saída. Depois, você pode escolher quais colunas deseja, sem precisar digitar todas elas.


13
Veja minha dica sobre como arrastar do SSMS
gbn

11

Basicamente, você não pode fazer o que gostaria - mas pode obter as ferramentas certas para ajudá-lo a facilitar um pouco as coisas.

Se você olhar para o prompt SQL da Red-Gate , poderá digitar "SELECT * FROM MyTable" e, em seguida, mover o cursor para trás após o "*" e pressionar <TAB> para expandir a lista de campos e remover os poucos campos que você deseja. não precisa.

Não é uma solução perfeita - mas muito boa! :-) Pena que o Intellisense do MS SQL Server Management Studio ainda não é inteligente o suficiente para oferecer esse recurso .......

Marc


Isso é bom, mas o problema é que sua consulta pode se tornar enorme. Seria bom ter o recurso "exceto", não para o código do produto, mas para consultas ad-hoc.
Micah B.

8

não, não há como fazer isso. talvez você possa criar visualizações personalizadas, se isso for possível na sua situação

EDIT Pode ser que seu banco de dados suporte a execução de sql dinâmico, você poderia escrever um SP e passar as colunas que você não quer ver e deixá-lo criar a consulta dinamicamente e retornar o resultado para você. Eu acho que isso é possível no SQL Server pelo menos


13
É factível, mas eu demitiria a pessoa que faz isso.
Lieven Keersmaekers

Problema clássico de limpeza: copie o dfata que você deseja manter em uma tabela temporária, trunque o maior, preencha novamente com a tabela temporária. Você precisa excluir a coluna de identidade.
Volker

8

Se você estiver usando o SQL Server Management Studio, faça o seguinte:

  1. Digite o nome da tabela desejada e selecione-o
  2. Pressione Alt+F1
  3. o / p mostra as colunas na tabela.
  4. Selecione as colunas desejadas
  5. Copie e cole aqueles na sua consulta selecionada
  6. Dispare a consulta.

Aproveitar.


7

No SQL Management Studio, você pode expandir as colunas no Pesquisador de Objetos e arrastar o Columnsitem da árvore para uma janela de consulta para obter uma lista de colunas separadas por vírgula.


6

Em resumo, você não pode fazê-lo, mas eu discordo de todos os comentários acima, "há" cenários em que você pode legitimamente usar um * Quando você cria uma consulta aninhada para selecionar um intervalo específico de uma lista inteira (como paginação) por que no mundo gostaria de especificar cada coluna na instrução de seleção externa quando você a fez no interior?


Você pode usar alguma variação de "innername. *" Para representar as colunas internas, semelhante a "SELECT table1. * ..." ao fazer uma junção?
Página Inicial>

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)

ATUALIZAR:

Você também pode criar um procedimento armazenado para cuidar dessa tarefa, se a usar com mais frequência. Neste exemplo, usei o STRING_SPLIT () que está disponível no SQL Server 2016 ou superior, mas se você precisar, existem muitos exemplos de como criá-lo manualmente no 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

E então apenas:

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

5

Se estamos falando de Procedimentos, ele trabalha com esse truque para gerar uma nova consulta e EXECUTE IMEDIATA :

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

Existe uma maneira de excluir colunas de uma tabela sem especificar todas as colunas?

Usando SQL declarativo da maneira usual, não.

Eu acho que a sintaxe proposta é válida e boa. De fato, a linguagem de banco de dados relacional 'Tutorial D' tem uma sintaxe muito semelhante, onde as palavras-chave ALL BUTsão seguidas por um conjunto de atributos (colunas).

No entanto, o SQL SELECT *já recebe muitas críticas (a resposta de @ Guffa aqui é uma objeção típica), então não acho que SELECT ALL BUTentrará no SQL Standard tão cedo.

Eu acho que a melhor solução é criar um VIEWcom apenas as colunas que você deseja SELECT * FROM ThatView.


1
@underscore_d: Agora revisei minha resposta.
onedaywhen

Legal, eu concordo com seus últimos 2 parágrafos. As informações sobre o Tutorial D são interessantes, embora eu tendem a concordar com aqueles que pensam que select *é questionável - muito útil para coisas e programas ad hoc que precisam lidar genericamente com tabelas de dados, mas não tanto para construir (na falta de uma palavra melhor) consultas 'puras'. Ainda assim, não estar no padrão ANSI não significa que a Microsoft não possa adicioná-lo ao dialeto, como em muitas outras coisas, mas estou cético quanto a isso.
underscore_d

5

Um dialeto SQL moderno como o BigQuery propõe uma excelente solução

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

Essa é uma sintaxe SQL muito poderosa para evitar uma longa lista de colunas que precisam ser atualizadas o tempo todo devido a alterações no nome da coluna da tabela. E essa funcionalidade está ausente na implementação atual do SQL Server, o que é uma pena. Felizmente, um dia, o Microsoft Azure será mais amigável para cientistas de dados.

Os cientistas de dados gostam de poder ter uma opção rápida para encurtar uma consulta e remover algumas colunas (devido a duplicação ou qualquer outro motivo).

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


4

O Postgres sql tem uma maneira de fazê-lo

os pls referem-se: http://www.postgresonline.com/journal/archives/41-How-to-SELECT-ALL-EXCEPT-some-columns-in-a-table.html

O esquema do esquema de informações

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

O exemplo acima para minha tabela de exemplo específica - gera uma instrução sql que se parece com isso

SELECIONE o.officepark, o.owner, o.squarefootage FROM officepark Como o


Embora isso possa teoricamente responder à pergunta, seria preferível incluir aqui as partes essenciais da resposta e fornecer o link para referência.
Bhargav Rao

3

Eu não conheço nenhum banco de dados que suporte isso (SQL Server, MySQL, Oracle, PostgreSQL). Definitivamente não faz parte dos padrões SQL, então acho que você deve especificar apenas as colunas que deseja.

Obviamente, você pode construir sua instrução SQL dinamicamente e pedir ao servidor que a execute. Mas isso abre a possibilidade de injeção de SQL.


3

Sei que isso é um pouco antigo, mas acabei de encontrar o mesmo problema e estava procurando uma resposta. Então, um desenvolvedor sênior me mostrou um truque muito simples.

Se você estiver usando o editor de consultas do studio de gerenciamento, expanda o banco de dados e expanda a tabela que você está selecionando para poder ver a pasta de colunas.

Na sua instrução select, apenas realce a pasta de colunas referenciadas acima e arraste e solte-a na janela de consulta. Ele colará todas as colunas da tabela e, em seguida, basta remover a coluna de identidade da lista de colunas ...


1
Sim, mas e se você tem 5 junta-se, a idéia seria fazerSELECT * Except(tableName.ColumnName) FROM ...
Pawel Cioch

Acho isso útil :) Eu não sabia disso, no entanto, essa não é uma resposta para a pergunta do tópico.
FKA

3

A melhor maneira de resolver isso é usando o view, você pode criar o view com as colunas necessárias e recuperar os dados

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
E se o número de colunas for grande, digamos 100 e queremos SELECIONAR todas as colunas, menos uma. Existe uma abordagem melhor?
KartikKannapur

5
Este meio que erra o ponto. Você está selecionando "id, data" na segunda chamada, que, se você quiser fazer isso, basta fazê-lo em primeiro lugar.
Keithpjolley

3

Se você deseja excluir uma coluna de maiúsculas e minúsculas, como a senha, por exemplo, faço isso para ocultar o valor:

SELECT * , "" as password FROM tableName;


este funcionou para mim
Arun Prasad ES

1
Embora você deva, é claro, nunca armazenar senhas de texto não criptografado em seu banco de dados. Pelo menos eles devem ser misturados com sal e talvez pimenta security.stackexchange.com/questions/3272/…
Anders_K

2

Bem, é uma prática recomendada comum especificar quais colunas você deseja, em vez de apenas especificar *. Portanto, você deve apenas indicar quais campos você deseja que sua seleção retorne.


2

Um colega aconselhou uma boa alternativa:

  • SELECT INTO na sua consulta anterior (de onde você gera ou obtém os dados) em uma tabela (que você excluirá quando terminar). Isso criará a estrutura para você.
  • Faça um script como CREATE para nova janela de consulta.
  • Remova as colunas indesejadas. Formate as colunas restantes em um forro 1 e cole como sua lista de colunas.
  • Exclua a tabela que você criou.

Feito...

Isso nos ajudou muito.


1

Clique com o botão direito do mouse na tabela no Pesquisador de Objetos, selecione as 1000 principais linhas

Ele listará todas as colunas e não *. Em seguida, remova as colunas indesejadas. Deve ser muito mais rápido do que digitar você mesmo.

Então, quando achar que isso é um pouco trabalhoso, obtenha o SQL Prompt do Red Gate e digite ssf de tbl, vá para o * e clique na guia novamente.


1

Que o que eu uso frequentemente para este caso:

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 parece column1,column2,column5


1

Às vezes, o mesmo programa deve lidar com diferentes estruturas de banco de dados. Portanto, não pude usar uma lista de colunas no programa para evitar erros noselect instruções.

*me dá todos os campos opcionais. Verifico se os campos existem na tabela de dados antes do uso. Esta é a minha razão para usar *emselect .

É assim que eu manejo campos excluídos:

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

Considere elaborar / esclarecer sua pergunta / problema.
Badfilms

1

Sei que esta pergunta é antiga, mas espero que ainda possa ser útil. A resposta é inspirada em uma discussão nos Fóruns do SQL Server . Você pode fazer disso um procedimento armazenado . Também pode ser modificado para adicionar mais de um, exceto campos.

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

Não seria mais simples fazer isso:

sp_help <table_name>

-Clique na coluna 'Nome_da_coluna'> Copiar> Colar (cria uma lista vertical) em uma janela Nova consulta e digite apenas vírgulas na frente do valor de cada coluna ... comente as colunas que você não deseja ... muito menos digitando do que qualquer código oferecido aqui e ainda gerenciável.


"muito menos digitação do que qualquer código oferecido aqui" e muito mais aborrecimento do que arrastar o nó Colunas para o editor de consultas ou qualquer outra maneira superior de obter a lista. Quero dizer, e as tabelas com muitos 10s de colunas?
underscore_d

0

Você pode obter o SQL Complete no devart.com, que não apenas expande o curinga *, como o Prompt do SQL do Red Gate (como descrito na resposta do cairnz), mas também fornece um seletor de colunas suspenso com caixas de seleção nas quais é possível verificar todas as colunas que você deseja na lista de seleção e elas serão inseridas automaticamente para você (e se você desmarcar uma coluna, ela será automaticamente removida da lista de seleção).


0

No SSMS, existe uma maneira mais fácil com IntelliSense e Aliasing . Tente isto

  1. Clique com o botão direito do mouse no editor de texto e verifique se o IntelliSense está ativado.
  2. Digite a consulta com um alias [SELECT t. * FROM tablename t].
  3. Vá o texto t. * E excluir o * e-list auto SSMS vontade as colunas da f mesa alias.
Em seguida, você pode especificar rapidamente apenas as colunas que deseja, sem precisar usar o SSMS para gravar uma seleção em outro script e executar mais operações de copiar / colar. Eu uso isso o tempo todo.


Você poderia especificar sua resposta para a exclusão de colunas, por favor?
21714 Kamiccolo

@ Kamiccolo - o que está sendo descrito pelo DuckWork é uma ação MANUAL. Recortando e colando os nomes das colunas desejadas. Ele está apenas dizendo que esta é uma maneira de obter mais facilmente os nomes, sem muita digitação. Isso não ajuda a escrever uma consulta que diz "excluir esta coluna". Isso apenas ajuda a criar a lista desejada de colunas, que você cola na sua consulta.
Home
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.