【问题标题】:How to select column name in select statement如何在选择语句中选择列名
【发布时间】:2014-04-25 11:03:55
【问题描述】:

我想将数据从表 A 复制/更新到表 B。表 B 有更多的列。我尝试了以下选项。

1) `REPLACE INTO `B` (SHOW FIELDS FROM 'A') SELECT * FROM `A

2) `REPLACE INTO `B` 
     (SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` 
              WHERE `TABLE_SCHEMA`='test1' AND `TABLE_NAME`='A') SELECT * FROM `A

但它会引发错误。你们能帮我如何使用选择查询选择名称吗?

更新:

3) 正如 Jerko 所建议的,

我有两张表 A(warehouse_id,long,lat) B(warehouse_id,long)

应用以下语句。

SET @query = CONCAT('REPLACE INTO `A` (SELECT  ', 
                     (SELECT GROUP_CONCAT(CONCAT('`',column_name, '`')) 
                      FROM information_schema.columns 
                      WHERE  `TABLE_SCHEMA`='test2' AND `table_name` = 'A'), 
                   ' FROM  `B`)');


PREPARE stmt FROM @query;
EXECUTE stmt;

这给了我错误

"#1054 - 'field list' 中的未知列 'lat'"

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    您不能像您尝试做的那样在 mysql 中动态地执行此操作。 MySQL 希望您的列名列表直接提供,而不是来自子查询。

    如果您想动态地执行此操作,您将不得不退回到您用于与 MySQL 交互的任何语言,例如 PHP 或 Java。

    【讨论】:

    • 需要提供字段名吗?
    • 使用另一种语言,如 PHP,您可以先查询表结构以获取列名,然后使用它来构建第二个查询。
    • @DushyantJoshi - 绝对是的。想想这个;如果它是自动的,你能想象 SQL 注入的奇妙 途径吗?基本上没有任何辩护 - 准备好的陈述不会有任何好处,因为它们处于错误的水平。所以没有理智的 RDBMS 会为你做自动扩展......并不是说它无论如何都能够区分常规数据和列名。
    【解决方案2】:

    你试过了吗?

    insert into B(col1, . . ., coln)
        select col1, . . ., coln
        from A;
    

    即在select 子句中列出来自A 的字段。在insert 列列表中列出B 的对应列。

    如果您需要列列表,请从INFORMATION_SCHEMA.COLUMNS 获取它们并剪切并粘贴到查询中。

    【讨论】:

    • 显然这会起作用。但我想选择列名作为选择语句
    • 您只能使用动态 SQL 执行此操作,使用 prepare 语句。即使这样,您也必须 100% 确定两个表中的列名相同,这是您的问题未提及的条件。
    • 另一个表有更多的列
    【解决方案3】:

    其实是有办法的

    SET @query = CONCAT('REPLACE INTO `A` (', 
                      (SELECT GROUP_CONCAT(CONCAT('`',column_name, '`')) 
                      FROM information_schema.columns 
                      WHERE  `TABLE_SCHEMA`='test1' AND `table_name` = 'A'
                      AND column_name IN (SELECT column_name FROM information_schema.columns WHERE table_schema = 'test1' AND table_name='B')) ,
                      ') (SELECT  ', 
                     (SELECT GROUP_CONCAT(CONCAT('`',column_name, '`')) 
                      FROM information_schema.columns 
                      WHERE  `TABLE_SCHEMA`='test1' AND `table_name` = 'A'
                      AND column_name IN (SELECT column_name FROM information_schema.columns WHERE table_schema = 'test1' AND table_name='B')), 
                   ' FROM  `B`)');
    
    
    PREPARE stmt FROM @query;
    EXECUTE stmt;
    

    【讨论】:

    • 谢谢,但它会抛出错误“#1064 - 您的 SQL 语法有错误;请查看与您的 MySQL 服务器版本相对应的手册,以获取正确的语法,以便在行的“NULL”附近使用1"。我从上面的查询中遗漏了什么吗?因为我以前从未使用过准备好的语句
    • 也许你给它错误的 table_schema 和表名?
    • 是的,这绝对是因为我输入了错误的 table_schema 名称并且它抛出了同样的错误
    • 哦,是的,这是我的错,我很抱歉。这听起来不错的解决方案,但我又得到了错误的列错误
    • 首先确保内部 SELECT 工作,然后确保您在表 A 中拥有表 B 中的所有列,也在这里发布错误,我们将对其进行调试
    【解决方案4】:

    试试这个

    INSERT INTO B (field1,field2,...,fieldN) 
            SELECT (field1,field2,...,fieldN) FROM A
    

    【讨论】:

    • 谢谢,但我需要字段作为子查询
    猜你喜欢
    • 1970-01-01
    • 2017-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-03
    • 1970-01-01
    相关资源
    最近更新 更多