SQL exclude a column using SELECT * [except columnA] FROM tableA?
我们都知道,要从表中选择所有列,可以使用
1 | SELECT * FROM tableA |
在不指定所有列的情况下,是否可以从表中排除列?
1 | SELECT * [EXCEPT columnA] FROM tableA |
号
我知道的唯一方法是手动指定所有列并排除不需要的列。这真的很耗时,所以我正在寻找节省时间和精力的方法,以及如果表有更多/更少的列,将来的维护。
谢谢!
我同意所有人…但如果我要做这样的事情,我可能会这样做:
1 2 3 4 5 6 7 8 9 | /* 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 |
号
不。
维护灯的最佳实践是只指定所需的列。
至少2个原因:
- 这使得客户机和数据库之间的契约稳定。每次相同的数据
- 性能,覆盖指标
编辑(2011年7月):
如果从对象资源管理器中拖动表的
在SQL(SQL Server)中执行此操作的自动方法是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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); |
如果不想手动写入每个列名,可以通过右键单击SSMS中的表或视图来使用
。
然后,您将在新的查询编辑器窗口中获得整个select查询,然后删除不需要的列,如下所示:
氧化镁
多恩
您可以创建一个视图,其中包含您想要选择的列,然后只需从该视图中选择*即可…
可以(但不推荐)。
1 2 3 4 5 6 7 8 9 10 11 | 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') |
代码说明:
就像其他人说的那样,没有办法做到这一点,但是如果您使用的是SQL Server,我使用的一个技巧是将输出更改为逗号分隔,然后执行
1 | SELECT top 1 * FROM TABLE |
并从输出窗口中剪切整个列列表。然后,您可以选择所需的列,而不必全部键入。
基本上,你不能做你想做的-但是你可以得到正确的工具来帮助你使事情变得简单一点。
如果查看Red Gate的SQL提示,您可以键入"select*from mytable",然后将光标移回"*"之后,单击
这不是一个完美的解决方案,而是一个该死的好办法!:-)太糟糕了,MS SQL Server Management Studio的IntelliSense仍然不够智能,无法提供此功能……。
马克
在SQL Management Studio中,您可以展开对象资源管理器中的列,然后将
不,没有办法。如果这在您的情况下可行,也许您可以创建自定义视图。
如果您的数据库支持动态SQL的执行,那么edit可能会编写一个sp并将您不希望看到的列传递给它,让它动态地创建查询并将结果返回给您。我认为这至少在SQL Server中是可行的
如果您使用的是SQL Server Management Studio,请执行以下操作:
享受。
总之,你不能这样做,但我不同意上面所有的评论,在"有"的情况下,你可以合法地使用*当您创建一个嵌套查询以从整个列表中选择一个特定的范围(如分页)时,为什么在内部完成后,世界上的每个列都希望在外部select语句中指定?
1 2 3 4 5 6 7 8 9 10 | 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) |
更新:
如果您更频繁地使用这个任务,您还可以创建一个存储过程来处理它。在这个示例中,我使用了内置的字符串_split(),它在SQL Server 2016+上可用,但是如果您需要的话,这里有很多关于如何手动创建它的例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 |
。
然后只是:
1 2 3 | EXEC [usp_select_without] @TABLE_NAME = N'Test_Table', @list_of_columns_excluded = N'ID, Date, Name'; |
号
Is there a way to exclude column(s) from a table without specifying
all the columns?
号
用通常的方式使用声明性SQL,不是。
我认为你提出的语法是值得和良好的。事实上,关系数据库语言"tutorial d"的语法非常相似,其中关键字
但是,SQL的
我认为最好的"解决方法"是创建一个
如果我们谈论的是过程,它将使用这个技巧生成一个新的查询并立即执行它:
1 2 3 4 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'); |
我不知道任何支持这个的数据库(SQL Server、MySQL、Oracle、PostgreSQL)。它绝对不是SQL标准的一部分,所以我认为您必须只指定所需的列。
当然,您可以动态地构建SQL语句并让服务器执行它。但这为SQL注入打开了可能性。
我知道这有点老了,但我刚遇到同样的问题,正在寻找答案。然后我让一个高级开发人员给我展示了一个非常简单的技巧。
如果正在使用Management Studio查询编辑器,请展开数据库,然后展开要从中选择的表,以便可以看到Columns文件夹。
在select语句中,只需突出显示上面的referenced columns文件夹,然后将其拖放到查询窗口中。它将粘贴表中的所有列,然后只需从列列表中删除标识列…
学院建议一个好的选择:
- 在前面的查询中选择into(在其中生成或获取从)到表(完成后将删除)的数据。这将为您创建结构。
- 在创建到新查询时执行脚本窗口。
- 删除不需要的列。设置其余列的格式放入1行并粘贴为列列表。
- 删除您的表创建。
完成。。。
这对我们帮助很大。
好吧,通常的最佳实践是指定所需的列,而不仅仅是指定*。因此,您应该只说明希望选择返回哪些字段。
解决这个问题的最佳方法是使用视图,您可以创建具有所需列的视图并从中检索数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 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) |
Postgres SQL有一种方法
请参考:http://www.postgreonline.com/journal/archives/41-how-to-select-all-except-some-columns-in-a-table.html
信息模式黑客方法
1 2 3 4 5 | 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语句如下所示
选择o.officepark、o.owner、o.squarefootage从officepark as o
右键单击对象资源管理器中的表格,选择前1000行
它将列出所有列,而不是*。然后移除不需要的列。应该比自己打字快得多。
然后,当您觉得这项工作有点太多时,获取RedGate的SQL提示,然后从tbl中键入ssf,转到*并再次单击选项卡。
有时同一个程序必须处理不同的数据库结构。所以我不能在程序中使用列列表来避免
这是我处理排除字段的方式:
1 2 3 4 5 6 7 8 | 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 2 3 4 5 | 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) |
这样做不是更简单吗:
1 | sp_help <table_name> |
号
-单击"列名称"列>复制>粘贴(创建垂直列表)到新的查询窗口中,然后在每个列值前面键入逗号…注释掉你不想要的列…打字比这里提供的任何代码都要少,而且还可以管理。
在SSMS中,智能感知和混叠有一种更简单的方法。试试这个
我是这样做的,它工作得很好(版本5.5.41):
1 2 3 4 5 6 7 8 9 10 11 12 | # 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; |
。
Bartoszx提出的答案(存储过程)在使用视图而不是实际表时对我不起作用。
这个想法和下面的代码(除了我的补丁)属于Bartoszx。
为了对表和视图都有效,请使用以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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 |
我知道这个问题由来已久,但我希望它仍然有帮助。这个答案受到了来自SQL Server论坛的讨论的启发。您可以将其设置为存储过程。它也可以修改为添加多个字段。
1 2 3 4 | 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 |
。
您可以从devart.com获得完整的SQL,它不仅像Red Gate中的SQL提示那样扩展*通配符(如Cairnz的回答中所述),而且还提供了一个列选择器下拉列表,其中包含复选框,您可以选中选择列表中所需的所有列,这些列将自动为您插入(如果您没有取消选中某列时,它将自动从选择列表中删除)。
这不会节省从数据库加载的时间。但是,您可以始终取消设置不希望位于其所在数组中的列。我在一张桌子上有几列,但不想有一列。我太懒了,不能把它们都写在select语句中。
1 2 3 4 5 6 7 8 9 | $i=0; $row_array = array(); while($row = mysqli_fetch_assoc($result)){ $row_array[$i]=$row; unset($row_array[$i]['col_name']); $i++; } |
号
如果这里有人像我一样使用MySQL:
1 2 3 4 5 6 7 | CREATE TABLE TempTable AS SELECT * FROM #YourTable; ALTER TABLE TempTable DROP COLUMN #YourColumn; SELECT * FROM TempTable; DROP TABLE TempTable; |
。
如果您使用的是MySQLWorkbench,那么可以右键单击表资源管理器,然后单击"发送到SQL编辑器->选择所有语句"。
它发送类似"select col1,col2,…"的语句。从表名"。
然后去掉那些你不需要的。
根据表的大小,可以将其导出到Excel中,并将其转置为新表,其中原始表的列将是新表中的行。然后将它带回您的SQL数据库,根据条件选择行,并将它们插入到另一个新表中。最后,将这个更新的表导出到Excel,并执行另一个转置操作以获得所需的表,并将其带回SQL数据库。
不确定是否可以在SQL数据库中执行转换,如果可以,则更简单。
杰夫
不,没有任何方法可以做到这一点,也没有很好的理由去做。
选择数据时,不应使用
当然,如果可能的话,这同样适用于
您可以使用regex列规范。
下面的查询选择除ds和hr之外的所有列从销售中选择