Select all columns except one in MySQL?
我正在尝试使用select语句来获取某个MySQL表中的所有列,除了一个。 有一个简单的方法吗?
编辑:此表中有53列(不是我的设计)
实际上有一种方法,你需要有权利这样做...
1 2 3 4 |
替换
1 2 3 |
在这种情况下,View会更好吗?
你可以做:
没有得到column3,虽然你可能正在寻找更通用的解决方案?
如果您要排除某个字段的值,例如对于安全问题/敏感信息,您可以将该列检索为null。
例如
据我所知,没有。你可以这样做:
并手动选择所需的列。但是,如果你想要很多列,那么你可能只想做一个:
并且忽略你不想要的东西。
在您的特定情况下,我建议:
除非你只想要几列。如果您只想要四列,那么:
没问题,但是如果你想要50列,那么任何使查询的代码都会变得(太?)难以阅读。
在尝试@Mahomedalid和@Junaid的解决方案时,我发现了一个问题。所以想分享它。如果列名称具有空格或连字符(如签入),则查询将失败。简单的解决方法是在列名称周围使用反引号。修改后的查询如下
1 2 3 4 |
如果您不想选择的列中包含大量数据,并且由于速度问题而您不想包含它,并且您经常选择其他列,我建议您创建一个新表使用您通常不会使用原始表的键选择的一个字段,并从原始表中删除该字段。在实际需要额外字段时加入表。
您可以使用DESCRIBE my_table并使用其结果动态生成SELECT语句。
我的主要问题是我在连接表时得到的很多列。虽然这不是您的问题的答案(如何从一个表中选择除某些列之外的所有列),但我认为值得一提的是您可以指定
以下是一个如何非常有用的示例:
1 2 3 4 5 6 7 8 9 |
结果是users表中的所有列,以及从元表连接的另外两列。
我喜欢
我们可以用Prepared语句的子查询中的where子句替换REPLACE函数,如下所示:
使用我的表和列名称
1 2 3 |
因此,这将仅排除字段
希望这能帮助任何寻求解决方案的人。
问候
即使查询所有列,最好指定要查询的列。
所以我建议你在声明中写下每一列的名称(不包括你不想要的那一列)。
做就是了
然后将列放在您最喜欢的编程语言中:php
1 2 3 4 5 6 |
我同意列出所有列的"简单"解决方案,但这可能是繁重的,而错别字会导致大量浪费的时间。我使用函数"getTableColumns"来检索适合粘贴到查询中的列的名称。然后,我需要做的就是删除那些我不想要的东西。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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; |
您的结果返回逗号分隔的字符串,例如......
col1,col2,col3,col4,...col53
起初我以为你可以使用正则表达式,但是因为我一直在阅读MYSQL文档,所以你似乎不能。如果我是你,我会使用另一种语言(如PHP)来生成您想要获取的列的列表,将其存储为字符串然后使用它来生成SQL。
同意@ Mahomedalid的回答。但我不想做像预备语句这样的事情,我不想输入所有字段。
所以我所拥有的是一个愚蠢的解决方案。
转到phpmyadmin-> sql-> select中的表,它转储查询副本替换并完成! :)
我同意
我将创建一个包含所需数据的视图,然后您可以
我也想要这个,所以我创建了一个函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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中你可以像这样使用它:
1 | mysql_query("SELECT".$db->getColsExcept('table',array('id','bigtextcolumn'))." FROM table"); |
要么
1 | mysql_query("SELECT".$db->getColsExcept('table','bigtextcolumn')." FROM table"); |
是的,虽然它可能是高I / O,这取决于表,这是我找到的解决方法。
1 2 3 4 5 6 7 8 |
也许我有一个解决Jan Koritak指出的差异的解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 |
表:
1 2 3 |
================================
1 2 3 4 | table_name column_name employee eid employee name_eid employee sal |
================================
查询结果:
1 | 'SELECT name_eid,sal FROM employee' |
虽然我同意托马斯的答案(+1;)),但我想补充一点,我会假设你不想要的专栏几乎没有任何数据。如果它包含大量文本,xml或二进制blob,则请花时间单独选择每个列。否则你的表现会受到影响。干杯!
根据@Mahomedalid的回答,我做了一些改进,以支持"选择除mysql中的一些列以外的所有列"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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
1 |
Mahomedalid发布的答案有一个小问题:
内部替换功能代码将"
我的建议:
1 2 3 4 5 |
替换
1 | 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 |
实际上,您只需要以这种方式提取列名称一次以构造排除该列的列列表,然后只使用您构造的查询。
所以类似于:
1 | 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) |
现在,您可以在构造的查询中重用
我想添加另一个观点来解决这个问题,特别是如果要删除少量列。
您可以使用像MySQL Workbench这样的数据库工具来为您生成select语句,因此您只需为生成的语句手动删除这些列并将其复制到SQL脚本中。
在MySQL Workbench中,生成它的方法是:
右键单击表 - >发送到Sql编辑器 - >选择所有语句。
如果它始终是相同的一列,那么您可以创建一个没有它的视图。
否则,不,我不这么认为。
我有一个建议,但没有解决方案。
如果您的某些列具有更大的数据集,那么您应该尝试使用以下内容
接受的答案有几个缺点。
- 它在表或列名称需要反引号的地方失败
- 如果要省略的列在列表中的最后一列,则会失败
- 它需要列出两次表名(一次用于select,另一次用于查询文本),这是多余的和不必要的
- 它可能以错误的顺序返回列名
所有这些问题都可以通过简单地在
1 2 3 4 5 6 7 8 9 10 11 12 13 |
我很晚才找到答案,这就是我一直这样做的方式,坦率地说,它比最好的答案好100倍,我只希望有人能看到它。并发现它很有用
1 2 3 4 5 6 7 8 9 10 11 12 | //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反模式。它不应该在生产代码中使用,原因有很多,包括:
处理需要更长的时间。当事情运行数百万次时,那些微小的位可能很重要。一个缓慢的数据库,其中由这种类型的草率编码引起的缓慢是最难的性能调整。
这意味着您可能发送的数据超出了您的需求,从而导致服务器和网络瓶颈。如果您有内部联接,则发送超出您需要的数据的可能性为100%。
它会导致维护问题,尤其是当您添加了不希望在任何地方看到的新列时。此外,如果您有新列,则可能需要对界面执行某些操作以确定如何处理该列。
它可以打破视图(我知道这在SQl服务器中是正确的,它可能在mysql中也可能不是真的)。
如果有人愚蠢地用不同的顺序重建表格(你不应该这样做,但它会发生在所有时间),各种代码都会破坏。特别是插入代码,例如突然你将城市放入address_3字段,因为没有指定,数据库只能按列的顺序排列。这在数据类型发生变化时已经足够糟糕了,但是当交换列具有相同的数据类型时更糟糕,因为您可能会在某些时候插入糟糕的数据来清理。您需要关心数据完整性。
如果在插入中使用它,如果在一个表中添加新列而不在另一个表中添加新列,则它将破坏插入。
它可能会破坏触发器。触发问题可能难以诊断。
将所有这些添加到列名称中添加所需的时间(哎呀,你甚至可能有一个允许你拖动列名称的界面(我知道我在SQL Server中做的,我敢打赌有一些方法可以这是你用来编写mysql查询的一些工具。)让我们看看,"我可能会导致维护问题,我可能会导致性能问题而且我可能会导致数据完整性问题,但是嘿,我节省了五分钟的开发时间。"真的只是放了在您想要的特定列中。
我还建议你读这本书: