Mysql 从两个具有相同列名的表中选择*

Mysql 从两个具有相同列名的表中选择*,mysql,Mysql,假设我有两个包含许多列的表,所以我不想在查询中显式地命名列名,但我想避免重复的名称 如果我这样做: CREATE TABLE new_table SELECT a.*, b.* FROM table1 a INNER JOIN table2 b ON a.myID = b.myId WHERE a.age > 10 and b.ice = 'melted' 我会得到一个错误:重复的列名myId,如果a和b中有更多的列名相同,我也会得到更多的错误 如何

假设我有两个包含许多列的表,所以我不想在查询中显式地命名列名,但我想避免重复的名称

如果我这样做:

  CREATE TABLE new_table
    SELECT a.*, b.*
    FROM  table1 a
    INNER JOIN table2 b ON a.myID = b.myId
    WHERE a.age > 10 and b.ice = 'melted'
我会得到一个错误:重复的列名myId,如果a和b中有更多的列名相同,我也会得到更多的错误

如何通过在a.*和b.*中的所有列名中自动添加前缀来避免此问题,而不显式地提及所有列名—这样做非常繁琐


谢谢

不幸的是,您将不得不在case表中列出具有匹配列名的列。但是,您可以使用information_schema获取列名,设置列名格式,并在查询中复制粘贴以节省时间,例如:

SELECT GROUP_CONCAT(CONCAT('a.', COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_SCHEMA = 'schema' AND TABLE_NAME = 'table';
上面的查询应该为您提供以逗号分隔的列名,并带有。前缀然后,您可以对表b使用相同的查询,取出名称并在主SELECT查询中使用它

更新

正如@uuerdo所说,您也可以向列中添加别名,例如:

SELECT GROUP_CONCAT(CONCAT('a.', COLUMN_NAME, ' AS a_', COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_SCHEMA = 'schema' AND TABLE_NAME = 'table';

根据我的经验,ORMs将运行一个初始的descripe查询,这样一旦有了列名,它就可以为您完成这类工作。但是,如果您坚持在单个查询中动态执行此操作,则可以使用纯MySQL执行此操作:

-- config
SET @database = 'your_database';
SET @tableA = 'table1';
SET @tableB = 'table2';

-- table alias "a" columns
SET @fieldsA = NULL;
SELECT GROUP_CONCAT(CONCAT('a.', COLUMN_NAME), ' AS ',CONCAT('`a.', COLUMN_NAME,'`')) INTO @fieldsA
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = @database AND TABLE_NAME = @tableA;

-- table alias "b" columns
SET @fieldsB = NULL;
SELECT GROUP_CONCAT(CONCAT('b.', COLUMN_NAME), ' AS ',CONCAT('`b.', COLUMN_NAME,'`')) INTO @fieldsB
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_SCHEMA = @database AND TABLE_NAME = @tableB;

-- some variables for readability
SET @fields = CONCAT(' ', @fieldsA, ',', @fieldsB,' ');
SET @tableAliasA = CONCAT(' ',@database, '.', @tableA,' a ');
SET @tableAliasB = CONCAT(' ',@database, '.', @tableB,' b ');


-- generate our final query
SET @query = CONCAT('CREATE TABLE new_table SELECT', @fields,
                     'FROM', @tableAliasA,
                     'INNER JOIN', @tableAliasB,
                     'ON a.myID = b.myId WHERE a.age > 10 and b.ice = ''melted''');

-- finally run the query:
PREPARE stmt1 FROM @query;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;

-- if you have problems with the above query, uncomment the following to get the query so you can run it separately
-- SELECT @query;
不过,我强烈建议不要使用这种解决方案。我最好像前面所说的那样运行一个初始的descripe查询,然后在此基础上生成您的查询。另一种解决方案是创建一个临时表作为第二个表的副本,然后重命名有问题的列,然后继续对其进行联接,以生成创建新表所需的数据。MySQL对于同名的结果列没有问题,这里的问题是试图创建一个包含两个同名列的表。所以基本上你要做的是一个星型选择,但不包括一列

另一种方法是仅从以下两个选项中选择主键: 选择a.myID作为'aId',b.myID作为'bId',然后创建只包含该内容的表。然后,如果您需要某个特定表中的数据,只需将JOIN留在该表中,即可获取所需的信息。您可以更进一步,设置一个视图来为您执行此类操作。视图可以为您连接表,并使您可以很容易地选择要查找的任何列。也可以设置多个视图。还请注意,视图的行为与用于连接的表类似。可以将视图与表联接,也可以将视图与视图联接,等等


而不是做你想做的事情——用另外两个表中的数据创建一个新表——考虑你是否真的在寻找一个.< /p>你必须别名你的列,OP,这意味着写出它们。也许您可以想出一种非常快速的方法来列出两个表中的所有列,并在它们之间加上逗号?尽管使用select*进行选择是很常见的做法,但这被认为是一种不好的做法;它会让您面临各种各样的问题,例如,当这样一列后来被添加到所使用的一个表中时,使用没有共同列名的表随机中断查询。。。任何半体面的查询编辑器都应该能够弹出一个列列表,以节省您的键入时间。@Uuerdo年轻的程序员会记住这一点,因为计算机是为计算机工作的,而不是为人类工作的。。。但是是有道理的。当你有100个专栏时,这是一种相当不理想的做事方式。我可以很容易地想象这样一个世界,SQL语言可以理解这种类型的查询,并在每个列名称中添加前缀。我不确定编码器的年龄与这些查询有什么关系,但SELECT*将继续是一种糟糕而懒惰的做法,直到计算机真正变得通灵。如果有什么区别的话,这将是一个连编码员都开始期望计算机为他们思考的时代。@Uuerdo*一点也不懒惰,它很方便,这是非常不同的。如果您可以在SQL语言p.*中作为p.p_*执行此操作,这意味着在SQL语言中显式定义所有列的名称并将它们更改为p_*会怎么样。那太懒了?不,那很方便。我想我想象的世界里,人工智能也被融入到编码中,因此编程变得更加灵活。只是因为它从来没有做过并不意味着永远不会做。我们以前必须用所有语言定义类型,例如C,然后python出现了,人们不必定义类型。编程是不断发展的。我想说,如果你想做这样的事情,请更进一步,做GROUP_Concat'a.,COLUMN_NAME.,AS a_'COLUMN_NAME@darshan有没有一种方法可以通过一个嵌套查询来实现最终目标?@Dnaiel你可以做到,但是,这很复杂。看一看。我建议您将结果存储在一个查询中,然后在第二个查询中使用它。