SQL使用SELECT *排除列 FROM tableA?
我们都知道要从表中select所有的列,我们可以使用
SELECT * FROM tableA
有没有一种方法来从表中排除列(s)而不指定所有的列?
SELECT * [except columnA] FROM tableA
我知道的唯一方法是手动指定所有列并排除不需要的列。 这是非常耗时的,所以我正在寻找节省时间和精力的方法,以及如果表格有更多/更less的列,将来的维护。
谢谢!
我同意每个人……但是如果我要这样做,我可以这样做:
/* 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
没有。
维护灯的最佳做法是仅指定所需的列。
至less有两个原因:
- 这使得您的客户端和数据库之间的合同稳定。 相同的数据,每次
- 性能,覆盖索引
编辑(2011年7月):
如果您从对象资源pipe理器中拖动表的“ Columns
节点,则会在查询窗口中为您添加一列CSV列表,以实现您的目标之一
在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);
如果您不想手动编写每个列名称,可以使用Script Table As
通过右键单击表或在SSMS中 查看 ,如下所示:
然后,您将在新build查询编辑器窗口中获得整个select查询,然后删除不需要的列,如下所示:
完成
你可以创build一个你想要select的列的视图,然后你可以从视图中select* …
是的,这是可能的(但不推荐)。
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')
代码解释 :
- 声明一个variables来存储逗号分隔的列名称列表。 这个默认为NULL。
- 使用系统视图来确定表中列的名称。
- 使用
SELECT @variable = @variable + ... FROM
连接列名称。 这种types的SELECT
不会返回结果集。 这可能是没有logging的行为,但适用于每个版本的SQL Server。 作为替代,你可以使用SET @variable = (SELECT ... FOR XML PATH(''))
连接string。 - 仅当这不是第一个列名称时,才使用
ISNULL
函数预先填充逗号。 使用QUOTENAME
函数来支持列名中的空格和标点符号。 - 使用
WHERE
子句来隐藏我们不想看到的列。 - 使用
EXEC (@variable)
,也称为dynamicSQL ,在运行时parsing列名。 这是需要的,因为我们不知道编译时的列名。
像其他人一样,有没有办法做到这一点,但如果你使用Sql Server的一个窍门,我使用的是改变输出到逗号分隔,然后做
select top 1 * from table
并从输出窗口中删除整列列表。 那么你可以select你想要的列,而不必全部input。
基本上,你不能做你想做的事,但你可以find合适的工具来帮助你做出更轻松的事情。
如果您查看Red-Gate的SQL提示符 ,您可以键入“SELECT * FROM MyTable”,然后将光标移回“*”后面,然后按<TAB>展开字段列表,然后删除这些字段不需要。
这不是一个完美的解决scheme – 但是一个很好的解决scheme! :-)太糟糕了MS SQL Server Management Studio的Intellisense仍然不够智能化,无法提供此function…….
渣子
不,没有办法做到这一点。 也许你可以创build自定义视图如果在你的情况下是可行的
编辑可能是如果你的数据库支持执行dynamicSQL你可以写一个SP并传递列不希望看到它,让它dynamic创build查询,并返回结果给你。 我认为这在SQL Server至less是可行的
总之,你不能这样做,但我不同意上面所有的评论,有“你”可以合法使用*的场景当你创build一个嵌套查询,以便从整个列表中select一个特定的范围分页)为什么在这个世界中想要在外部select语句中指定每一列时,在内部完成它呢?
在SQL Management Studio中,您可以展开对象资源pipe理器中的列,然后将“ Columns
树项目拖动到查询窗口中以获取逗号分隔的列列表。
如果您正在使用SQL Server Management Studio,请执行如下操作:
- input你想要的表名并select它
- 按下Alt + F1
- o / p显示表中的列。
- select所需的列
- 复制并粘贴您的select查询
- 启动查询。
请享用。
如果我们正在谈论程序,它会使用这个技巧来生成一个新的查询,并立即执行它:
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');
有没有一种方法来从表中排除列(s)而不指定所有的列?
以通常的方式使用声明式SQL,否。
我认为你提出的语法是值得的和好的。 事实上,关系数据库语言“Tutorial D”中的关键字ALL BUT
后面跟着一组属性(列),语法非常相似。
然而,SQL的SELECT *
已经得到了很多(@ Guffa的答案是一个典型的异议),所以我不认为SELECT ALL BUT
会很快进入SQL标准。
我认为最好的“解决办法”是创build一个只有你想要的列然后SELECT * FROM ThatView
。
我不知道任何支持这个的数据库(SQL Server,MySQL,Oracle,PostgreSQL)。 这绝对不是SQL标准的一部分,所以我认为你只需要指定你想要的列。
你当然可以dynamic地build立你的SQL语句并让服务器执行它。 但是这开辟了SQL注入的可能性。
那么,指定你想要的列是最常见的做法,而不是指定*。 所以你应该说明你希望你的select返回哪个字段。
一位同事build议一个好的select:
- 在前面的查询中(你从哪里产生或从中获取数据)SELECT INTO到一个表(你将在完成时删除)。 这将为您创build结构。
- 做一个脚本作为CREATE到新的查询窗口。
- 删除不需要的列。 将剩余的列格式化为1,然后粘贴为列列表。
- 删除你创build的表。
完成…
这对我们帮助很大。
我知道这是有点老,但我刚刚遇到同样的问题,正在寻找答案。 然后我有一个高级开发人员向我展示了一个非常简单的技巧
如果您使用的是pipe理工作室查询编辑器,请展开数据库,然后展开您正在select的表格,以便可以看到列文件夹。
在您的select语句中,只需突出显示上面引用的列文件夹并将其拖放到查询窗口即可。 它将粘贴表格的所有列,然后只是从列的列表中删除标识列…
在对象资源pipe理器中右键单击表格,select前1000行
它会列出所有列,而不是*。 然后删除不需要的列。 应该比自己打字快得多。
然后,当你觉得这样做有点太多的时候,得到Red Gate的SQL提示符,然后从tbl中inputssf,进入*然后再次点击选项卡。
这是我经常用于这种情况:
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
有时同一个程序必须处理不同的数据库结构。 所以我不能在程序中使用列列表来避免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
解决这个问题的最好方法是使用视图,您可以创build具有所需列的视图并从中检索数据
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)
不,没有办法做到这一点,没有理由这样做。
select数据时不应该使用*
,您应该始终指定所需的字段。 原因是即使稍后向表中添加另一个字段,也希望查询的工作方式相同。 另外,您还要指定结果中字段的顺序,以便重新排列表中的字段不会改变结果。
当然, * except
可以这样做的情况* except
,这一点也是适用的。
根据您的表的大小,您可以将其导出到Excel中,并将其转置为具有新表格,其中原始表格的列将成为新表格中的行。 然后将其放回到SQL数据库中,并根据条件select行并将其插入到另一个新表中。 最后,将这个较新的表格导出到Excel中,并执行另一个转置以获得所需的表格并将其转回到SQL数据库。
不知道tranpose是否可以在SQL数据库中完成,如果是,那么它会更容易。
杰夫
这样做会不会更简单:
sp_help <table_name>
– 点击“Column_name”列>复制>粘贴(创build一个垂直列表)到一个新的查询窗口,只需在每个列值的前面input逗号…注释掉你不想要的列…更less打字比在这里提供的任何代码,仍然可以pipe理。
你可以从devart.com得到SQL Complete,它不仅像Red Gate的SQL Prompt那样扩展了*通配符(如cairnz的回答中所述),而且还提供了一个列select器下拉列表框,您可以在其中检查所有你想在select列表中的列,他们会自动插入你(如果你然后取消选中列将自动从select列表中删除)。
在SSMS中,使用智能感知和别名的方法更简单。 尝试这个
- 在文本编辑器中右键单击并确保IntelliSense已启用。
- 用别名键入查询[SELECT t。* FROM tablename t]。
- 转到文本t。*并删除* ,SSMS将自动列出别名表的列。
然后,您可以快速指定仅需要使用SSMS将不需要使用SSMS 的列写入另一个脚本的列,然后执行更多的复制/粘贴操作。 我一直用这个
这不会节省从数据库加载的时间。 但是,你总是可以在你放置的数组中放置不需要的列。我在表中有好几列,但是不想要一个列。 我懒得把它们写在SELECT语句中。
$i=0; $row_array = array(); while($row = mysqli_fetch_assoc($result)){ $row_array[$i]=$row; unset($row_array[$i]['col_name']); $i++; }
我这样做,它工作得很好(版本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;
我知道这个问题是旧的,但我希望这仍然是有益的。答案是从SQL Server论坛1的讨论启发。 你可以把这个存储过程。 它也可以被修改为添加多个字段除外。 第一列不能是例外。
Declare @TBNAME sysname, @SQL NVARCHAR(MAX), @Exception VARCHAR(500) SET @TBNAME = 'tableName' SET @Exception = 'columnName' SELECT @SQL = COALESCE(@SQL + '', '') + SQL FROM ( SELECT 'SELECT ' + COLUMN_NAME As SQL, 1 As SQLGroup FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TBNAME AND ORDINAL_POSITION = 1 UNION ALL SELECT ', ' + COLUMN_NAME As SQL, 2 As SQLGroup FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TBNAME AND ORDINAL_POSITION <> 1 AND COLUMN_NAME <> @Exception UNION ALL SELECT ' FROM ' + TABLE_NAME As SQL, 3 As SQLGroup FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @TBNAME ) As S ORDER BY SQLGroup SELECT @SQL --OR EXEC sp_executesql @SQL
我发布上面的解决scheme后,我有一个更好的主意:
DECLARE @SQL NVARCHAR(MAX) SELECT @SQL = COALESCE(@SQL + ', ', ' ' ) + name from sys.columns where name <> 'colName' and object_id = (Select id from sysobjects where name = 'tblName') SELECT @SQL = 'SELECT ' + @SQL + ' FROM ' + 'tblName' EXEC sp_executesql @SQL