[英]how to select * from tableA where columnA values don't start with letter 'F'
[英]Exclude a column using SELECT * [except columnA] FROM tableA?
我们都知道要从表中选择所有列,我们可以使用
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
不。
轻量级最佳实践是仅指定所需的列。
至少有2个原因:
编辑(2011 年 7 月):
如果您从对象资源管理器中拖动表的Columns
节点,它会为您在查询窗口中放置一个列的 CSV 列表,这实现了您的目标之一
如果您不想手动编写每个列名,您可以通过右键单击表或在SSMS 中查看来使用Script Table As
,如下所示:
然后您将在新查询编辑器窗口中获得整个选择查询,然后删除不需要的列,如下所示:
完毕
在 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);
您可以创建一个包含要选择的列的视图,然后您只需从视图中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')
代码说明:
SELECT @variable = @variable + ... FROM
连接列名。 这种类型的SELECT
不返回结果集。 这可能是未记录的行为,但适用于 SQL Server 的每个版本。 作为替代方案,您可以使用SET @variable = (SELECT ... FOR XML PATH(''))
来连接字符串。ISNULL
函数在前面添加逗号。 使用QUOTENAME
函数支持列名称中的空格和标点符号。WHERE
子句隐藏我们不想看到的列。EXEC (@variable)
,也称为动态 SQL ,在运行时解析列名。 这是必需的,因为我们在编译时不知道列名。像 BigQuery 这样的现代 SQL 方言提出了一个很好的解决方案
SELECT * EXCEPT(ColumnNameX, [ColumnNameY, ...])
这是一种非常强大的 SQL 语法,可以避免由于表列名更改而需要一直更新的一长列列。 而这个功能在目前的 SQL Server 实现中是缺失的,很可惜。 希望有一天,Microsoft Azure 对数据科学家更加友好。
数据科学家喜欢能够有一个快速选项来缩短查询并能够删除一些列(由于重复或任何其他原因)。
https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#select-modifiers
就像其他人所说的那样,没有办法做到这一点,但是如果您使用的是 Sql Server,我使用的一个技巧是将输出更改为逗号分隔,然后执行
select top 1 * from table
并从输出窗口中剪切整个列列表。 然后,您可以选择所需的列,而无需全部输入。
基本上,你不能做你想做的事——但你可以得到正确的工具来帮助你让事情变得更容易。
如果您查看 Red-Gate 的SQL Prompt ,您可以键入“SELECT * FROM MyTable”,然后将光标移回“*”之后,然后点击 <TAB> 以展开字段列表,并删除您选择的那几个字段不需要。
这不是一个完美的解决方案 - 而是一个非常好的解决方案! :-) 太糟糕了 MS SQL Server Management Studio 的 Intellisense 仍然不够智能,无法提供此功能......
马克
不,没有办法做到这一点。 如果在您的情况下可行,也许您可以创建自定义视图
编辑可能是如果您的数据库支持动态 sql 的执行,您可以编写一个 SP 并将您不想看到的列传递给它,让它动态创建查询并将结果返回给您。 我认为这至少在 SQL Server 中是可行的
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';
在 SQL Management Studio 中,您可以在对象资源管理器中展开列,然后将Columns
树项拖到查询窗口中以获得逗号分隔的列列表。
如果您使用的是 SQL Server Management Studio,请执行以下操作:
享受。
例如,如果你想排除一个敏感的大小写列,比如密码,我这样做是为了隐藏值:
SELECT * , "" as password FROM tableName;
如果我们在谈论过程,它可以使用这个技巧来生成一个新的查询并立即执行它:
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,不。
我认为你提出的语法是值得的和好的。 事实上,关系数据库语言“教程 D”具有非常相似的语法,其中关键字ALL BUT
后跟一组属性(列)。
然而,SQL 的SELECT *
已经受到了很多批评(@Guffa 在这里的回答是典型的反对意见),所以我认为SELECT ALL BUT
不会很快进入 SQL 标准。
我认为最好的“解决方法”是创建一个仅包含您想要的列的VIEW
然后SELECT * FROM ThatView
。
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 FROM officepark As o
解决此问题的最佳方法是使用视图,您可以创建具有所需列的视图并从中检索数据
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)
我不知道有任何支持此功能的数据库(SQL Server、MySQL、Oracle、PostgreSQL)。 它绝对不是 SQL 标准的一部分,所以我认为你必须只指定你想要的列。
您当然可以动态构建 SQL 语句并让服务器执行它。 但这开启了 SQL 注入的可能性。
我知道这有点旧,但我刚刚遇到了同样的问题并正在寻找答案。 然后我让一位高级开发人员向我展示了一个非常简单的技巧。
如果您使用的是 management studio 查询编辑器,请展开数据库,然后展开您从中选择的表,以便您可以看到列文件夹。
在您的选择语句中,只需突出显示上面引用的列文件夹并将其拖放到查询窗口中。 它将粘贴表的所有列,然后只需从列列表中删除标识列...
好吧,指定您想要的列是一种常见的最佳实践,而不是仅仅指定 *. 因此,您应该只说明您希望选择返回哪些字段。
右键单击对象资源管理器中的表,选择前 1000 行
它将列出所有列而不是 *. 然后删除不需要的列。 应该比自己打字快得多。
然后当你觉得这有点太多工作时,获取 Red Gate 的 SQL Prompt,然后从 tbl 中键入 ssf,转到 * 并再次单击选项卡。
在 Hive Sql 中,您可以这样做:
set hive.support.quoted.identifiers=none;
select
`(unwanted_col1|unwanted_col2|unwanted_col3)?+.+`
from database.table
这给了你剩下的 cols
实际上snowflake 刚刚发布了exclude
所以现在你只需:
SELECT * EXCLUDE [columnA,columnB,...] FROM tableA
一位同事提出了一个不错的选择:
完毕...
这对我们帮助很大。
我经常在这种情况下使用的内容:
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
我知道这个问题很老,但我希望这仍然有帮助。答案的灵感来自SQL Server 论坛的讨论。 您可以将其设为存储过程。 也可以修改为添加多个字段(字段除外)。
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
当使用视图而不是真实表时,来自 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
在SSMS中, IntelliSense和Aliasing是一种更简单的方法。 尝试这个
这将不会节省从数据库加载的时间。 但是,您始终可以在其放置的数组中取消设置不需要的列。我在表中有几列,但又不想有一个特定的列。 我懒得将它们全部写在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;
如果这里有人像我一样使用MySql,请使用:
CREATE TABLE TempTable AS SELECT * FROM #YourTable;
ALTER TABLE TempTable
DROP COLUMN #YourColumn;
SELECT * FROM TempTable;
DROP TABLE TempTable;
这样做不是更简单吗:
sp_help <table_name>
- 单击“Column_name”列> 复制> 粘贴(创建一个垂直列表)到新查询窗口中,然后在每个列值前键入逗号...注释掉您不想要的列...少得多打字比这里提供的任何代码都好,而且仍然易于管理。
以下是生成要在查询中使用的列列表(不是自动查询,因为未指定):
SELECT
GROUP_CONCAT(
CONCAT('`', `COLUMN_NAME`, '`')
SEPARATOR ',\n'
) AS `cols`
FROM information_schema.`COLUMNS`
WHERE `TABLE_SCHEMA` = 'db'
AND `TABLE_NAME` = 'table_name_here'
AND `COLUMN_NAME` NOT IN ('exclude_col1', 'exclude_col2')
将产生:
`included_col1`,
`included_col2`,
`included_col3`
然后,您可以复制它以在查询中使用:
SELECT
`included_col1`,
`included_col2`,
`included_col3`
FROM db.table_name_here
简单的解决方案。 在 SSMS 中,找到您的表,右键单击它,然后将表编写为脚本,然后选择到。 查询将与列出的每一列一起写出。 注释掉或删除您不想要的列。 忽略列的非常快速和简单的解决方案。
尝试这个...
=QUERY(TRANSPOSE(QUERY('Data'!A1:AH,"SELECT * ",1)),"SELECT * WHERE Col1 <> 'Column
name'",1)
DECLARE @Columns NVARCHAR(MAX)='',@SQL NVARCHAR(MAX)
SELECT @Columns=CASE WHEN @Columns='' THEN name ELSE @Columns+','+name END
FROM sys.columns
WHERE object_ID=(sELECT id FROM sysobjects WHERE name='TheTableName') and NAME!='WithoutColumnName'
SELECT @SQL='SELECT '+@Columns+' FROM dbo.TheTableName'
EXEC sp_execute @SQL
当然,正如他们所说的,您需要使用动态 sql 来实现。 这是我的实现:
SET NOCOUNT ON
DECLARE @Table NVARCHAR(100) = 'Table' --Table to Select
DECLARE @ExcludeColumns AS TABLE (ColumnName VARCHAR(255))
INSERT INTO @ExcludeColumns VALUES ('ExcludedColumn1'),('ExcludedColumn2') --Excluded columns
DECLARE @SelectedColumns NVARCHAR(MAX) = ''
SELECT
@SelectedColumns += CASE WHEN LEN(@SelectedColumns) = 0 THEN '' ELSE ',' END + '[' + COLUMN_NAME + ']'
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = @Table AND COLUMN_NAME NOT IN (SELECT ColumnName FROM @ExcludeColumns)
DECLARE @sqlStatement NVARCHAR(MAX) = 'SELECT ' + @SelectedColumns + ' FROM [' + @Table + ']'
PRINT @sqlStatement
EXEC (@sqlStatement)
如果您有很多列并且只想排除一列。您可以使用下面的命令 Select * exclude(column name) from Table
您可以从 devart.com 获取 SQL Complete,它不仅像 Red Gate 的 SQL Prompt 一样扩展了 * 通配符(如 cairnz 的回答中所述),而且还提供了一个带有复选框的列选择器下拉菜单,您可以在其中选中所有您想要在选择列表中的列,它们将自动为您插入(如果您随后取消选中某个列,它将自动从选择列表中删除)。
根据表格的大小,您可以将其导出到 Excel 并将其转置为一个新表格,其中原始表格的列将成为新表格中的行。 然后将其带回您的 SQL 数据库并根据条件选择行并将它们插入到另一个新表中。 最后将这个较新的表导出到 Excel 并进行另一个转置以获得所需的表并将其带回您的 SQL 数据库。
不确定转置是否可以在 SQL 数据库中完成,如果是,那么它会更容易。
杰夫
如果您使用的是 mysql-workbench,您可以右键单击表资源管理器,然后单击“发送到 SQL 编辑器->选择所有语句”。
它发送类似“Select col1, col2,... from tablename”的语句。
然后删除那些你不需要的。
不,没有任何方法可以做到这一点,也没有充分的理由这样做。
在选择数据时,您永远不应该使用*
,您应该始终指定所需的字段。 原因是您希望即使您稍后向表中添加另一个字段,查询也能正常工作。 您还可以指定结果中字段的顺序,以便重新排列表中的字段不会更改结果。
当然,这同样适用于* except
可以这样做。
您可以使用 REGEX 列规范。
以下查询选择除 ds 和 hr 之外的所有列 SELECT (ds|hr)?+.+
FROM sales
如果您使用的是 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.