选择MySQL以外的所有列?

Tom*_*icz 346 mysql select wildcard

我正在尝试使用select语句来获取某个MySQL表中的所有列,除了一个.有一个简单的方法吗?

编辑:此表中有53列(不是我的设计)

Mah*_*lid 209

实际上有一种方法,你需要有权利这样做...

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;
Run Code Online (Sandbox Code Playgroud)

更换 <table>, <database> and <columns_to_omit>

  • 警告:INFORMATION_SCHEMA查询的性能相当差,所以要小心这种类型的查询不在任何关键路径中. (19认同)
  • 就像@Jan Koritak在下面所说的那样,如果您要删除的标题列也是您希望保留的任何列的标题的子字符串,则此答案实际上不起作用.[这里有一个更好的答案,可以在这里找到](http://stackoverflow.com/questions/2365972/how-can-i-select-from-a-table-in-mysql-but-省略-某些柱/ 13808457#13808457). (7认同)
  • 这比仅指定已知最佳实践的列更糟糕. (6认同)
  • 如果要忽略的列是表结构中列出的最后一列(因为替换将与尾随昏迷不匹配),这也将不起作用. (3认同)
  • 如果列名称中有空格,则此方法无效.它应该更新为始终用反引号"<column_name>"中的名称括起来 (2认同)

bor*_*nac 52

在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;
Run Code Online (Sandbox Code Playgroud)

  • 在第3步给出了错误消息:"列数与第1行的值计数不匹配".所以我将第2步更改为"UPDATE temp_tb SET id = NULL"然后它工作了. (3认同)
  • @Karan 要重复运行此查询,请在开头添加另一个命令:`DROP TABLE IF EXISTS temp_tb; ` (3认同)
  • 好的,这有效。但是当我再次运行这个查询时,它给了我一个错误,即 temp_tb 已经存在。temp_tb 在内存中存在多长时间?如果这是一个愚蠢的问题,请道歉。PS 对你的回答投了赞成票。 (2认同)
  • @Karan 要指定内存引擎,请使用命令:`CREATE TEMPORARY TABLE temp_tb ENGINE=MEMORY (SELECT * FROM orig_tb); ` ,否则默认情况下它会保存到磁盘,并且在服务器重新启动后仍然存在。([感谢](/sf/ask/1410107611/)) (2认同)

Bri*_*ess 42

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

CREATE VIEW vwTable
as  
SELECT  
    col1  
    , col2  
    , col3  
    , col..  
    , col53  
FROM table
Run Code Online (Sandbox Code Playgroud)

  • 哈哈!当然可以.现在,您如何构建视图以包括所有BUT中的一列.我想你看到这是如何引发原始问题的.事实上,我特意找到了这个线程,因为我想创建一个排除某些列的视图,而不必强制在视图定义中明确列出所有剩余的列. (9认同)

Mik*_*one 35

你可以做:

SELECT column1, column2, column4 FROM table WHERE whatever
Run Code Online (Sandbox Code Playgroud)

没有得到column3,虽然你可能正在寻找更通用的解决方案?

  • +1来抵消downvote.虽然这是一个天真的答案,但这是完全正确的,我认为这是"一种简单的方法". (24认同)
  • OP说有> 50列,所以这是不切实际的. (23认同)
  • @DanielPryden,它实际上是一个比投票更高的答案更正确的答案.这不是天真的. (4认同)
  • 实际上,出于维护原因,拥有"除了"之外的所有查询都很有用.否则,如果稍后添加新字段,则必须更新显式字段列表. (4认同)
  • 大多数评分较高的答案大多只是寻找无需手动输入即可生成此确切查询的方法 (2认同)

Sea*_*n O 29

如果您要排除字段的值,例如,出于安全问题/敏感信息,您可以将该列检索为null.

例如

SELECT *, NULL AS salary FROM users
Run Code Online (Sandbox Code Playgroud)

  • SQL始终允许在结果集中使用重复的列名.如果你希望这个工作,你需要使用不支持dupes的客户端应用程序运行它*并且*优先考虑最后一个欺骗.官方命令行客户端支持欺骗.HeidiSQL也支持它们.[SQL Fiddle](http://sqlfiddle.com/#!2/f7e53/1)没有,但显示*first*dupe,而不是last.总结一下:**这不起作用**. (63认同)
  • 为什么?它不起作用.如果你有一个列工资,那么这个查询最终会得到两个名为salary的列,一个满是空,一个带有实际工资. (12认同)
  • 当然它不起作用.这是为什么你应该在mysql本身测试答案的一个很好的例子,而不是通过与mysql交谈的库. (9认同)
  • @SeanO,@ Alastair,@ Everyone,**不覆盖.**服务器仍然返回敏感数据. (7认同)
  • @Myforwik这个查询确实添加了第二个`salary`列.但是因为它是在*之后检索的,所以它会覆盖原始的.它不漂亮,但确实有效. (4认同)
  • @SeanO抱歉这不起作用. (3认同)
  • 不行.返回两列,一列包含数据,另一列包含空值 (2认同)
  • 如果您获取“Object”或“Assoc”,它将覆盖列 (2认同)

Tho*_*ens 21

据我所知,没有.你可以这样做:

SELECT col1, col2, col3, col4 FROM tbl
Run Code Online (Sandbox Code Playgroud)

并手动选择所需的列.但是,如果你想要很多列,那么你可能只想做一个:

SELECT * FROM tbl 
Run Code Online (Sandbox Code Playgroud)

并且忽略你不想要的东西.

在您的特定情况下,我建议:

SELECT * FROM tbl
Run Code Online (Sandbox Code Playgroud)

除非你只想要几列.如果您只想要四列,那么:

SELECT col3, col6, col45, col 52 FROM tbl
Run Code Online (Sandbox Code Playgroud)

没问题,但是如果你想要50列,那么任何使查询的代码都会变得(太?)难以阅读.

  • 总是选择*是一个糟糕的选择.不推荐它.阅读它为什么是SQl反模式. (3认同)

小智 16

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

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;
Run Code Online (Sandbox Code Playgroud)


Sta*_*rds 11

如果您不想选择的列中包含大量数据,并且由于速度问题而您不想包含它,并且您经常选择其他列,我建议您创建一个新表使用您通常不会使用原始表的键选择的一个字段,并从原始表中删除该字段.在实际需要额外字段时加入表.


jam*_*kes 9

您可以使用DESCRIBE my_table并使用其结果动态生成SELECT语句.


cwd*_*cwd 7

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

以下是一个如何非常有用的示例:

select users.*, phone.meta_value as phone, zipcode.meta_value as zipcode

from users

left join user_meta as phone
on ( (users.user_id = phone.user_id) AND (phone.meta_key = 'phone') )

left join user_meta as zipcode
on ( (users.user_id = zipcode.user_id) AND (zipcode.meta_key = 'zipcode') )

结果是users表中的所有列,以及从元表连接的另外两列.

  • 谢谢,我需要选择第一个表的所有列,加入第二个表中只有一个字段,你的回答对我有帮助. (2认同)

小智 5

是的,尽管它可能是高 I/O,具体取决于表,这是我为它找到的解决方法。

SELECT *
INTO #temp
FROM table

ALTER TABLE #temp DROP COlUMN column_name

SELECT *
FROM #temp
Run Code Online (Sandbox Code Playgroud)


Jun*_*aid 5

我喜欢这个回答,@Mahomedalid除了这个事实,评论来自@Bill Karwin.提出的可能问题@Jan Koritak是真的,我遇到了这个,但我找到了一个技巧,只是想在这里分享面对这个问题的任何人.

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

使用我的表和列名称

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;
Run Code Online (Sandbox Code Playgroud)

因此,这将仅排除字段,id但不排除company_id

希望这能帮助任何寻求解决方案的人.

问候