select除MySQL之外的所有列?

我试图使用select语句来获取除了一个以外的某个MySQL表中的所有列。 有一个简单的方法来做到这一点?

编辑:这个表中有53列(不是我的devise)

其实有一个办法,你需要有权限,当然这样做…

SET @sql = CONCAT('SELECT ', (SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME), '<columns_to_omit>,', '') FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '<table>' AND TABLE_SCHEMA = '<database>'), ' FROM <table>'); PREPARE stmt1 FROM @sql; EXECUTE stmt1; 

replace<table>, <database> and <columns_to_omit>

在这种情况下,View会更好吗?

 CREATE VIEW vwTable as SELECT col1 , col2 , col3 , col.. , col53 FROM table 

在mysql定义(手动)中没有这样的事情。 但是,如果您有大量列col1 ,…, col100 ,以下是有用的:

 mysql> CREATE TEMPORARY TABLE temp_tb SELECT * FROM orig_tb; mysql> ALTER TABLE temp_tb DROP col_x; mysql> SELECT * FROM temp_tb; 

你可以做:

 SELECT column1, column2, column4 FROM table WHERE whatever 

没有得到column3,但也许你正在寻找一个更一般的解决scheme?

如果您正在寻找排除一个字段的值,例如为了安全考虑/敏感信息,您可以将该列检索为空。

例如

 SELECT *, NULL AS salary FROM users 

据我所知,没有。 你可以做一些事情:

 SELECT col1, col2, col3, col4 FROM tbl 

并手动select你想要的列。 但是,如果你想要很多列,那么你可能只想做一个:

 SELECT * FROM tbl 

而忽略你不想要的东西。

在你的具体情况下,我会build议:

 SELECT * FROM tbl 

除非你只想要几列。 如果你只需要四列,那么:

 SELECT col3, col6, col45, col 52 FROM tbl 

会很好,但如果你想要50列,那么任何使查询的代码将变得(太?)难以阅读。

如果您不想select的列中包含大量数据,并且由于速度问题您不想包含它,而且您经常select其他列,那么我build议您创build一个新表与您通常不select一个字段的原始表的一个键,并从原始表中删除该字段。 实际需要额外字段时join表格。

在通过@Mahomedalid和@Junaid尝试解决scheme时,我发现了一个问题。 所以想到分享它。 如果列名具有空格或连字符(如签入),则查询将失败。 简单的解决方法是围绕列名使用反引号。 修改后的查询如下

 SET @SQL = CONCAT('SELECT ', (SELECT GROUP_CONCAT(CONCAT("`", COLUMN_NAME, "`")) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'users' AND COLUMN_NAME NOT IN ('id')), ' FROM users'); PREPARE stmt1 FROM @SQL; EXECUTE stmt1; 

您可以使用DESCRIBE my_table并使用它的结果dynamic生成SELECT语句。

我的主要问题是连接表时遇到的许多列。 虽然这不是你的问题的答案(如何从一个表中select除了某些列以外的所有列),但我认为值得一提的是你可以指定table. 从一个特定的表中获取所有的列,而不是仅仅指定。

这是一个如何可能非常有用的例子:

select用户。*,phone.meta_value作为电话,zipcode.meta_value作为邮政编码

来自用户

留下joinuser_meta作为电话
 on((users.user_id = phone.user_id)AND(phone.meta_key ='phone'))

左joinuser_meta作为邮政编码
 on((users.user_id = zipcode.user_id)AND(zipcode.meta_key ='zipcode'))

结果是users表中的所有列以及从meta表连接的两个附加列。

即使查询所有列,指定要查询的列也是很好的做法。

所以我build议你在声明中写下每一列的名字(不包括你不想要的)。

 SELECT col1 , col2 , col3 , col.. , col53 FROM table 

我喜欢@Mahomedalid的回答,除了来自@Bill Karwin评论。 @Jan Koritak提出的可能的问题是我所面对的,但我已经find了一个技巧,只是想在这里分享给面临这个问题的任何人。

我们可以用Prepared语句的子查询中的where子句replaceREPLACE函数,如下所示:

使用我的表和列的名称

 SET @SQL = CONCAT('SELECT ', (SELECT GROUP_CONCAT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'users' AND COLUMN_NAME NOT IN ('id')), ' FROM users'); PREPARE stmt1 FROM @SQL; EXECUTE stmt1; 

所以,这将只排除字段id但不包括company_id

希望这会帮助任何人寻找解决scheme。

问候

我同意列出所有列的“简单”解决scheme,但这可能是繁重的,错别字可能会导致大量浪费时间。 我使用“getTableColumns”函数来检索适合粘贴到查询中的列的名称。 那么我需要做的就是删除那些我不想要的东西。

 CREATE FUNCTION `getTableColumns`(tablename varchar(100)) RETURNS varchar(5000) CHARSET latin1 BEGIN DECLARE done INT DEFAULT 0; DECLARE res VARCHAR(5000) DEFAULT ""; DECLARE col VARCHAR(200); DECLARE cur1 CURSOR FOR select COLUMN_NAME from information_schema.columns where TABLE_NAME=@table AND TABLE_SCHEMA="yourdatabase" ORDER BY ORDINAL_POSITION; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; OPEN cur1; REPEAT FETCH cur1 INTO col; IF NOT done THEN set res = CONCAT(res,IF(LENGTH(res)>0,",",""),col); END IF; UNTIL done END REPEAT; CLOSE cur1; RETURN res; 

你的结果返回逗号分隔的string,例如…

COL1,COL2,COL3,COL4,… col53

我同意Select *是不够的,如果那个你不需要的,就像其他地方提到的那样,是一个BLOB,你不想让这个头顶上的蠕变进来。

我会用所需的数据创build一个视图 ,然后您可以Select * ,以便数据库软件支持它们。 否则,将庞大的数据放在另一个表中。

起初我以为你可以使用正则expression式,但正如我一直在阅读MYSQL文档 ,似乎你不能。 如果我是你,我会使用另一种语言(如PHP)来生成你想要得到的列的列表,把它作为一个string存储,然后用它来生成SQL。

我也想这个,所以我创build了一个函数。

 public function getColsExcept($table,$remove){ $res =mysql_query("SHOW COLUMNS FROM $table"); while($arr = mysql_fetch_assoc($res)){ $cols[] = $arr['Field']; } if(is_array($remove)){ $newCols = array_diff($cols,$remove); return "`".implode("`,`",$newCols)."`"; }else{ $length = count($cols); for($i=0;$i<$length;$i++){ if($cols[$i] == $remove) unset($cols[$i]); } return "`".implode("`,`",$cols)."`"; } } 

所以它是如何工作的,你进入表中,然后是你不想要的列或数组:array(“id”,“name”,“whatevercolumn”)

所以在select你可以像这样使用它:

 mysql_query("SELECT ".$db->getColsExcept('table',array('id','bigtextcolumn'))." FROM table"); 

要么

 mysql_query("SELECT ".$db->getColsExcept('table','bigtextcolumn')." FROM table"); 

虽然我同意托马斯的回答(+1;),但是我想补充说明的是,我将假设您想要的列中几乎包含任何数据。 如果它包含大量文本,xml或二进制blob,请花时间分别select每个列。 否则你的performance会受到影响。 干杯!

做就是了

 SELECT * FROM table WHERE whatever 

然后把列放在你最喜欢的编程语言:PHP

 while (($data = mysql_fetch_array($result, MYSQL_ASSOC)) !== FALSE) { unset($data["id"]); foreach ($data as $k => $v) { echo"$v,"; } } 

是的,虽然它可以是高I / O取决于这里是我find了解决方法。

 Select * into #temp from table alter table #temp drop column column_name Select * from #temp 

Mahomedalid发布的答案有一个小问题:

里面的replace函数代码是用“”replace“ <columns_to_delete>, ”,如果replace字段是由于最后一个string没有char逗号“不会从string中删除。

我的build议:

 SET @sql = CONCAT('SELECT ', (SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME), '<columns_to_delete>', '\'FIELD_REMOVED\'') FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '<table>' AND TABLE_SCHEMA = '<database>'), ' FROM <table>'); 

replace<table><database>和`

删除的列被replacestring“FIELD_REMOVED”在我这种情况下,这是因为我试图安全的内存。 (我正在删除的字段是1MB左右的BLOB)

基于@Mahomedalid的答案,我已经做了一些改进,以支持“select除mysql以外的所有列”

 SET @database = 'database_name'; SET @tablename = 'table_name'; SET @cols2delete = 'col1,col2,col3'; SET @sql = CONCAT( 'SELECT ', ( SELECT GROUP_CONCAT( IF(FIND_IN_SET(COLUMN_NAME, @cols2delete), NULL, COLUMN_NAME ) ) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tablename AND TABLE_SCHEMA = @database ), ' FROM ', @tablename); SELECT @sql; 

如果你有很多cols,使用这个sql来改变group_concat_max_len

 SET @@group_concat_max_len = 2048; 

可能是我有一个解决scheme, 杨Koritak指出的差异

 SELECT CONCAT('SELECT ', ( SELECT GROUP_CONCAT(t.col) FROM ( SELECT CASE WHEN COLUMN_NAME = 'eid' THEN NULL ELSE COLUMN_NAME END AS col FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'employee' AND TABLE_SCHEMA = 'test' ) t WHERE t.col IS NOT NULL) , ' FROM employee' ); 

表:

 SELECT table_name,column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'employee' AND TABLE_SCHEMA = 'test' 

================================

 table_name column_name employee eid employee name_eid employee sal 

================================

查询结果:

 'SELECT name_eid,sal FROM employee' 

如果它总是同一列,那么你可以创build一个没有它的视图。

否则,我不这么认为。

您可以使用SQL生成SQL,如果您喜欢并评估它生成的SQL。 这是一个通用的解决scheme,因为它从信息模式中提取列名。 这里是Unix命令行的一个例子。

  • MYSQL与你的mysql命令
  • TABLE与表名
  • EXCLUDEDFIELD与排除的字段名称
 echo $(echo 'select concat("select ", group_concat(column_name) , " from TABLE") from information_schema.columns where table_name="TABLE" and column_name != "EXCLUDEDFIELD" group by "t"' | MYSQL | tail -n 1) | MYSQL 

实际上只需要以这种方式提取列名一次来构造排除该列的列列表,然后只使用您构build的查询。

所以像这样:

 column_list=$(echo 'select group_concat(column_name) from information_schema.columns where table_name="TABLE" and column_name != "EXCLUDEDFIELD" group by "t"' | MYSQL | tail -n 1) 

现在,您可以在您构build的查询中重复使用$column_liststring。

我想补充另一个观点来解决这个问题,特别是如果你有less量的列删除。

您可以使用像MySQL Workbench这样的DB工具来为您生成select语句,因此您只需手动删除生成语句的这些列并将其复制到您的SQL脚本。

在MySQL Workbench中,生成它的方法是:

右键单击表 – >发送到Sql编辑器 – >select所有语句。

同意@ Mahomedalid的答案。 但是我不想做一些准备好的陈述,而我也不想input所有的字段。 所以我所做的是一个愚蠢的解决scheme。 转到phpmyadmin-> sql-> select中的表,它将转储查询副本replace完成! 🙂

我很晚才回答这个问题,这就是我一直这样坦率地说的,比其最好的答案好100倍,我只希望有人能看到答案。 并find有用的

  //create an array, we will call it here. $here = array(); //create an SQL query in order to get all of the column names $SQL = "SHOW COLUMNS FROM Table"; //put all of the column names in the array foreach($conn->query($SQL) as $row) { $here[] = $row[0]; } //now search through the array containing the column names for the name of the column, in this case i used the common ID field as an example $key = array_search('ID', $here); //now delete the entry unset($here[$key]); 

select*是一个SQL反模式。 它不应该用于生产代码有很多原因,包括:

处理需要更长的时间。 当事情运行数百万次时,那些微小的比特就可能很重要。 一个缓慢的数据库,其中缓慢的这种types的草率编码是最难的performance调整。

这意味着你可能发送的数据比你需要的多,这会导致服务器和networking瓶颈。 如果你有一个内部联接,发送更多的数据的机会比你需要的是100%。

这会导致维护问题,尤其是当您添加了您不想到处看到的新列时。 此外,如果你有一个新的列,你可能需要做一些事情来界面,以确定如何处理该列。

它可以打破意见(我知道SQl服务器是这样,在mysql中可能会也可能不是这样)。

如果某个人足够愚蠢,以不同的顺序(不应该这样做,而是每次都发生这种情况)重build表,那么各种代码都可能被破坏。 特别是代码插入,例如,突然之间,你将城市放入address_3字段因为没有指定,数据库只能按列的顺序。 当数据types发生变化时,这是不够的,而当交换的列具有相同的数据types时会更糟糕,因为您可能需要插入坏数据来清理。 你需要关心数据的完整性。

如果在插入中使用它,如果在一个表中添加新列而不是在另一个表中添加新列,将会中断插入。

它可能会触发触发器。 触发问题可能难以诊断。

把所有这一切加起来,以添加列名称(你可能甚至有一个接口,可以拖动列的名称(我知道我在SQL Server做的,我敢打赌有一些方法来这是你用来编写mysql查询的一些工具。)让我们看看:“我可以导致维护问题,我可以导致性能问题,我可以导致数据完整性问题,但是,我保存了五分钟的开发时间。”真的只是把在你想要的特定的列。

我也build议你阅读这本书: http ://www.amazon.com/SQL-Apatpatterns-Programming-Pragmatic-Programmers-ebook/dp/B00A376BB2/ref=sr_1_1?s=digital-text& ie= UTF8& qid= 1389896688& sr=1- 1关键字= SQL +反模式