提问



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


SELECT * FROM tableA


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


SELECT * [except columnA] FROM tableA


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


谢谢!

最佳参考


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


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


没有。


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


至少有两个原因:



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



编辑(2011年7月):


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

其它参考2


在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


如果您不想手动编写每个列名,可以通过右键单击 SSMS 中的表或视图来使用Script Table As喜欢这个:





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





完成

其它参考4


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

其它参考5


是的,这是可能的(但不推荐)。


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


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


select top 1 * from table


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

其它参考7


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


如果查看Red-Gate的SQL提示符,可以键入SELECT * FROM MyTable,然后将光标移回*后面,然后点击< TAB>以展开字段列表,并删除它们你不需要的几个领域。[38]


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


渣子

其它参考8


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


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

其它参考9


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

其它参考10


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

其它参考11


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



  1. 输入您想要的表名称并选择它

  2. Alt + F1

  3. o/p显示表格中的列。

  4. 选择所需的列

  5. 复制&将这些内容粘贴到您选择的查询中

  6. 解雇查询。



请享用。

其它参考12


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


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

其它参考13



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



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


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


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


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

其它参考14


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)

其它参考15


我知道这有点老了,但我刚遇到同样的问题,正在寻找答案。然后我有一个高级开发人员给我看一个非常简单的技巧。


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


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

其它参考16


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


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

其它参考17


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

其它参考18


一位大学建议一个很好的选择:



  • 在前面的查询中执行SELECT INTO(生成或获取的位置)
    数据来自)到表中(完成后将删除)。这会
    为你创造结构。

  • 将脚本作为CREATE执行到新查询
    窗口。

  • 删除不需要的列。格式化其余列
    进入1个衬垫并粘贴为列列表。

  • 删除您的表格
    创建。



完成...


这对我们很有帮助。

其它参考19


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


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)

其它参考20


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


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


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

其它参考21


这是我经常使用的情况:


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

其它参考22


有时,同一程序必须处理不同的数据库结构。所以我无法在程序中使用列列表来避免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

其它参考23


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


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


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

其它参考24


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


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


杰夫

其它参考25


这样做不会更简单:


sp_help <table_name>


- 单击Column_name列>复制>粘贴(创建垂直列表)到新建查询窗口,然后在每个列值前面键入逗号...注释掉您不想要的列...远远少于键入比这里提供的任何代码,仍然可管理。

其它参考26


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

其它参考27


在SSMS中,使用 IntelliSense 别名可以更轻松地实现。试试这个

  1. 在文本编辑器中单击鼠标右键,确保已启用 IntelliSense
  2. 使用别名[[SELECT t。* FROM tablename t]]键入查询。
  3. 转到文字 t。* 并删除* ,SSMS会自动列出 f 别名表的列。

然后,您可以快速指定只有您想要的列,而不必使用SSMS将select写入另一个脚本,然后执行更多的复制/粘贴操作。
我经常用这个。

其它参考28


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


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

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

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

其它参考29


我这样做了,它工作正常(版本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;