SQL使用SELECT * [除了columnA] FROM tableA排除列?

时间:2009-04-08 09:15:28

标签: sql sql-server tsql

我们都知道要从表中选择所有列,我们可以使用

SELECT * FROM tableA

有没有办法在不指定所有列的情况下从表中排除列?

SELECT * [except columnA] FROM tableA

我知道的唯一方法是手动指定所有列并排除不需要的列。这非常耗时,所以我正在寻找节省时间和精力的方法,以及如果表格中有更多/更少的列,将来的维护。

谢谢!

43 个答案:

答案 0 :(得分:395)

我同意所有人的意见......但如果我打算这样做,我可以这样做:

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

答案 1 :(得分:275)

没有

维护 - 灯光最佳做法是仅指定所需的列。

至少有两个原因:

  • 这使您在客户端和数据库之间的合同稳定。
  • 每次都有相同的数据
  • 表现,涵盖指数

编辑(2011年7月):

如果您从对象资源管理器拖动表的Columns节点,它会在查询窗口中为您创建一个列的CSV列表,以实现您的目标之一

答案 2 :(得分:63)

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

答案 3 :(得分:58)

如果您不想手动编写每个列名,可以通过右键单击 SSMS <中的视图来使用Script Table As / em>像这样:

enter image description here

然后,您将在新查询编辑器窗口中获得完整的选择查询,然后删除不需要的列,如下所示:

enter image description here

完成

答案 4 :(得分:35)

您可以创建一个包含您想要选择的列的视图,然后您只需从视图中选择* ...

答案 5 :(得分:23)

是的可能(但不推荐)。

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 )来解析 运行时的列名。这是必需的,因为我们在编译时不知道列名。

答案 6 :(得分:17)

就像其他人说过没有办法做到这一点,但是如果你使用的是Sql Server,我使用的一个技巧就是将输出更改为逗号分隔,然后执行

select top 1 * from table

并从输出窗口中剪切整个列列表。然后,您可以选择所需的列,而无需全部输入。

答案 7 :(得分:11)

基本上,你不能做你想做的事 - 但你可以得到合适的工具来帮助你让事情变得更容易。

如果查看Red-Gate的SQL Prompt,可以输入“SELECT * FROM MyTable”,然后将光标移回“*”后面,然后点击&lt; TAB&gt;扩展字段列表,并删除那些您不需要的字段。

这不是一个完美的解决方案 - 但是一个很好的解决方案! :-)太糟糕了MS SQL Server Management Studio的Intellisense仍然不够智能,无法提供此功能.......

马克

答案 8 :(得分:7)

没有办法做到这一点。也许你可以创建自定义视图,如果这在你的情况下是可行的

编辑可能是你的数据库支持执行动态sql你可以编写一个SP并传递你不想看到它的列,让它动态创建查询并返回结果给你。我认为这在SQL Server至少是可行的

答案 9 :(得分:7)

如果您使用的是SQL Server Management Studio,请执行以下操作:

  1. 输入您想要的表名称并选择它
  2. Alt + F1
  3. o / p显示表格中的列。
  4. 选择所需的列
  5. 复制&amp;将这些内容粘贴到您选择的查询中
  6. 解雇查询。
  7. 享受。

答案 10 :(得分:7)

在SQL Management Studio中,您可以展开对象资源管理器中的列,然后将Columns树项拖到查询窗口中,以获得以逗号分隔的列列表。

答案 11 :(得分: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';

答案 12 :(得分:6)

总而言之,你不能这样做,但我不同意上面的所有评论,那里有你可以合法使用*的场景 当您创建嵌套查询以便从整个列表中选择特定范围(例如分页)时,为什么当您在内部选择语句中指定每个列时,为什么要在外部select语句中指定每个列?

答案 13 :(得分:5)

  

有没有办法在没有指定的情况下从表中排除列   所有的栏目?

以通常的方式使用声明性SQL,no。

我认为你提出的语法是值得的。实际上,关系数据库语言“Tutorial D”的语法非常相似,其中关键字ALL BUT后跟一组属性(列)。

然而,SQL的SELECT *已经有很多抨击(@ Guffa的回答是典型的反对意见),所以我认为SELECT ALL BUT不会很快进入SQL标准。

我认为最好的“解决方法”是创建VIEW,只包含您想要的列SELECT * FROM ThatView

答案 14 :(得分:5)

如果我们谈论的是程序,它可以使用这个技巧来生成一个新的查询并 EXECUTE IMMEDIATE 它:

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

答案 15 :(得分:3)

我知道这有点旧,但我遇到了同样的问题并且正在寻找答案。然后我让一位高级开发人员向我展示了一个非常简单的技巧。

如果您使用的是管理工作室查询编辑器,请展开数据库,然后展开您选择的表,以便可以看到列文件夹。

在select语句中,只需突出显示上面引用的列文件夹,然后将其拖放到查询窗口中即可。它将粘贴表的所有列,然后只需从列表列中删除标识列...

答案 16 :(得分:3)

我不知道任何支持此功能的数据库(SQL Server,MySQL,Oracle,PostgreSQL)。它绝对不是SQL标准的一部分,所以我认为你只需要指定你想要的列。

您当然可以动态构建SQL语句并让服务器执行它。但这开启了SQL注入的可能性..

答案 17 :(得分:2)

一位同事提出了一个很好的选择:

  • 在前面的查询中执行SELECT INTO(您生成或获取的位置) 数据来自)到表中(完成后将删除)。这将 为你创造结构。
  • 将脚本作为CREATE执行到新查询 窗口。
  • 删除不需要的列。格式化剩余的列 进入1个衬垫并粘贴为列列表。
  • 删除你的表格 创建。

完成...

这对我们有很大的帮助。

答案 18 :(得分:2)

像BigQuery这样的现代SQL方言提出了一个很好的解决方案

  

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

这是一种非常强大的SQL语法,可以避免由于表列名更改而导致需要长时间更新的一长列列。可惜的是,当前的SQL Server实现中缺少此功能。希望有一天,Microsoft Azure将对数据科学家更加友好。

数据科学家希望能够有一个快速的选项来缩短查询并能够删除某些列(由于重复或任何其他原因)。

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

答案 19 :(得分:2)

嗯,通常的最佳做法是指定所需的列,而不是仅指定*。所以你应该只说明你希望你的选择返回哪些字段。

答案 20 :(得分:2)

Postgres sql有办法做到这一点

请参阅: 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 As o

答案 21 :(得分:2)

解决此问题的最佳方法是使用视图,您可以创建包含所需列的视图并从中检索数据

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)

答案 22 :(得分:1)

在Hive Sql中,您可以执行以下操作:

set hive.support.quoted.identifiers=none;
select 
    `(unwanted_col1|unwanted_col2|unwanted_col3)?+.+`
from database.table

这给你剩下的cols

答案 23 :(得分:1)

右键单击对象资源管理器中的表,选择前1000行

它会列出所有列而不是*。然后删除不需要的列。应该比自己打字要快得多。

然后当您觉得这有点太多工作时,获取Red Gate的SQL提示符,并从tbl键入ssf,再次转到*并单击选项卡。

答案 24 :(得分:1)

例如,如果要排除诸如密码之类的敏感大小写列,我可以这样做来隐藏值:

SELECT * , "" as password FROM tableName;

答案 25 :(得分: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

答案 26 :(得分: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

答案 27 :(得分:0)

简单的解决方案。在 SSMS 中,找到您的表,右键单击它,然后将表编写为脚本,然后选择到。查询将与列出的每一列一起写出。注释掉或删除您不想要的列。忽略列的非常快速和简单的解决方案。

答案 28 :(得分:0)

试试这个...

=QUERY(TRANSPOSE(QUERY('Data'!A1:AH,"SELECT * ",1)),"SELECT * WHERE Col1 <> 'Column 
 name'",1)

答案 29 :(得分:0)

使用视图而不是真实表时,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

答案 30 :(得分:0)

def hungry(filename):
    food = open(filename)
    yumm=[]
    for line in food:
        yumm= yumm + line.split(" ")

    print(yumm)
hungry("3/nomnom.txt")

答案 31 :(得分:0)

我知道这个问题很老,但我希望这仍然有用。答案的灵感来自SQL Server Forums的讨论。您可以将其设为stored procedure。它也可以修改为添加多个字段除外。

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

答案 32 :(得分:0)

我是这样做的,它运行得很好(版本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;

答案 33 :(得分:0)

这不会节省从数据库加载的时间。但是,你总是可以在它所放置的数组中取消你不想要的列。我在表中有几列,但不想要一个特定的列。我太懒了,无法在SELECT语句中全部写出来。

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

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

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

答案 34 :(得分:0)

在SSMS中,使用 IntelliSense 别名有一种更简单的方法。试试这个

  1. 在文本编辑器中单击鼠标右键,确保已启用 IntelliSense
  2. 使用别名[SELECT t。* FROM tablename t]键入查询。
  3. 转到 t。* 文本并删除 * ,SSMS会自动列出 f 的列别名表。
然后,您可以快速指定只有您想要的列,而不必使用SSMS将select写入另一个脚本,然后执行更多的复制/粘贴操作。 我一直都在用这个。

答案 35 :(得分:0)

你可以从devart.com获得SQL Complete,它不仅像扩展Red Gate的SQL Prompt那样扩展*通配符(如cairnz的回答中所述),而且还提供了一个列选择器下拉列表,其中包含复选框检查选择列表中所需的所有列,它们将自动为您插入(如果您取消选中一列,它将自动从选择列表中删除。)

答案 36 :(得分:0)

这样做会不会更简单:

sp_help <table_name>

- 点击'Column_name'列&gt;复制和GT;粘贴(创建一个垂直列表)到一个新的查询窗口,只需在每个列值前面键入逗号...注释掉你不想要的列...远远少于这里提供的任何代码,并且仍然可以管理。< / p>

答案 37 :(得分:-1)

如果这里的任何人正在使用MySql,就像我使用的那样:

CREATE TABLE TempTable AS SELECT * FROM #YourTable; 

ALTER TABLE TempTable 
DROP COLUMN #YourColumn; 

SELECT * FROM TempTable; 
DROP TABLE TempTable;

答案 38 :(得分:-1)

如果您使用的是PHP,则只需进行查询,然后可以取消设置特定元素:

$sql = "SELECT * FROM ........ your query";
    $result = $conection->query($sql); // execute your query
    $row_cnt = $result->num_rows;   

if ($row_cnt > 0) {
        while ($row = $result->fetch_object()) {
            unset($row->your_column_name); // Exclude column from your fetch
            $data[] = $row;
}
echo json_encode($data); // or whatever

答案 39 :(得分:-1)

如果你正在使用mysql-workbench,你可以右键单击表浏览器并单击“发送到SQL编辑器 - >选择所有语句”。

它发送一个声明,例如“从表名中选择col1,col2,...”。

然后删除那些你不需要的东西。

答案 40 :(得分:-1)

根据表的大小,您可以将其导出到Excel并将其转置为一个新表,其中原始表的列将是新表中的行。然后将其恢复到SQL数据库并根据条件选择行并将它们插入另一个新表中。最后将这个较新的表导出到Excel并进行另一个转置以获得所需的表并将其恢复到SQL数据库。

不确定是否可以在SQL数据库中完成转置,如果是,那么它将更容易。

杰夫

答案 41 :(得分:-2)

不,没有办法做到这一点,没有充分的理由去做。

选择数据时绝不能使用*,您应该始终指定所需的字段。原因是即使稍后向表中添加另一个字段,您也希望查询的工作方式相同。您还可以指定结果中字段的顺序,以便重新排列表中的字段不会更改结果。

如果有可能的话,同样适用于* except

答案 42 :(得分:-3)

您可以使用REGEX列规范。

以下查询选择除ds和hr之外的所有列 SELECT (ds|hr)?+.+ FROM sales