我试图使用一个选择语句从某个MySQL表中获得除一个以外的所有列。有什么简单的方法吗?

编辑:在这个表格中有53列(不是我的设计)


当前回答

基于@Mahomedalid的答案,我做了一些改进,以支持“选择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;

其他回答

如果愿意,可以使用SQL生成SQL,并对生成的SQL进行评估。这是一种通用的解决方案,因为它从信息模式中提取列名。下面是一个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

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

比如:

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)

现在可以在构造的查询中重用$column_list字符串。

即使要查询所有列,也最好指定要查询的列。

因此,我建议您在语句中写下每一列的名称(不包括您不想要的列)。

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

FROM table

公认的答案有几个缺点。

当表或列名需要反引号时,该方法失败 如果要省略的列位于列表的最后,则会失败 它需要列出两次表名(一次用于选择文本,另一次用于查询文本),这是多余和不必要的 它可能以错误的顺序返回列名

所有这些问题都可以通过在GROUP_CONCAT的分隔符中包含反勾号并使用WHERE条件而不是REPLACE()来克服。出于我的目的(我想很多人也是如此),我希望列名按照它们在表中出现的顺序返回。为了实现这一点,我们在GROUP_CONCAT()函数中使用了显式的ORDER BY子句:

SELECT CONCAT(
    'SELECT `',
    GROUP_CONCAT(COLUMN_NAME ORDER BY `ORDINAL_POSITION` SEPARATOR '`,`'),
    '` FROM `',
    `TABLE_SCHEMA`,
    '`.`',
    TABLE_NAME,
    '`;'
)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE `TABLE_SCHEMA` = 'my_database'
    AND `TABLE_NAME` = 'my_table'
    AND `COLUMN_NAME` != 'column_to_omit';

如果你使用MySQL工作台,你可以右键单击你的表,点击发送到sql编辑器,然后选择所有语句,这将创建一个所有字段都被列出的语句,如下所示:

SELECT `purchase_history`.`id`,
    `purchase_history`.`user_id`,
    `purchase_history`.`deleted_at`
FROM `fs_normal_run_2`.`purchase_history`;
SELECT * FROM fs_normal_run_2.purchase_history;

现在你可以删除那些你不想要的。

在尝试@Mahomedalid和@Junaid的解决方案时,我发现了一个问题。所以我想分享一下。如果列名中有空格或连字符(如check-in),则查询将失败。简单的解决方法是在列名周围使用反标记。修改后的查询如下

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;