2017-08-23 124 views
2

让我们说我有很多列两个表,所以我不希望我的查询中明确命名的列名,但我想避免重名。SELECT * FROM具有相同的列名的两个表的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' 

我会得到一个错误说:duplicate column name myId,我也得到更多的错误,如果A和B更列名是相同的。 。

我如何通过在*和b自动添加前缀的所有列名来避免此问题* W/O明确提到的所有列名 - 非常繁琐这样做!

谢谢!

+1

你必须你的别名列,OP,这意味着写出来。也许你可以想出一个非常快捷的方式,用两个表之间的逗号来列出两个表中的所有列? – JNevill

+2

无论如何,它被认为是一个糟糕的(即使相当普遍的)练习用'SELECT *'选择;它会向您提供各种问题(例如,在随后将这些列添加到所使用的表中的一个表中时,这会“随机”使用没有共用列名的表中断公共查询)。 _...以及任何半面体查询编辑器都应该能够吐出列列表以便为您节省打字时间。@ – Uueerdo

+0

@Uueerdo年轻的编码人员会记住这是计算机为计算机工作而不是为人类工作的时间......但是是有道理的。当你有100列的时候,这会成为一个不太理想的方式去做事情。我很容易想象一个世界,在这个世界中,SQL语言可以理解这种类型的查询并为每个列名添加前缀 – Dnaiel

回答

1

以我的经验奥姆斯将运行初始DESCRIBE查询,以便它可以做一旦它有列名称,这种东西适合你。但是,如果你坚持在一个查询动态做这件事,你可以用纯的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; 

我强烈建议不要使用这种解决方案虽然。我会尽早运行一个初始的DESCRIBE查询,然后根据它生成查询。另一种解决方案是创建一个临时表作为第二表的副本,然后重命名有问题的栏目,然后继续加入它来产生您需要创建NEW_TABLE数据。 MySQL对于具有相同名称的结果列没有任何问题,这里的问题是试图创建一个具有两个具有相同名称的列的表。所以基本上你想要做的是明星选择,但不包括列。

另一种方法是仅从两个选项中选择主键:
SELECT a.myID as `aId`, b.myId as `bId`然后创建仅包含该表的表。然后,如果您需要某个特定表格的数据,只需加入它即可获取您要查找的信息。你可以更进一步,并建立一个视图为你做这种事情。视图可以为您连接表格,并可以非常轻松地选择您要查找的任何列。您也可以设置多个视图。还要注意,视图的行为就像连接目的的表一样。您可以使用表格加入视图,或者您可以加入视图等。

因此,而不是做你正在尝试做的事 - 用另外两个表中的数据创建一个新表 - - 考虑你是否真的在寻找VIEW

3

不幸的是,你将不得不列出情况表有列名匹配的列。但是,您可以使用information_schema得到的列名,格式和那些在查询中复制粘贴保存疼痛,例如:

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

上面的查询应该给你逗号,a.前缀分隔的列名。然后,您可以对表b使用相同的查询,将名称取出并在主要的SELECT查询中使用它。

更新

由于@Uueerdo说得好,你可以添加别名栏为好,如:

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

我想说如果你打算做这样的事情,可以进一步做一下,并做'GROUP_CONCAT(CONCAT('a。',COLUMN_NAME,'AS a_',COLUMN_NAME))' – Uueerdo

+0

@darshan有没有办法在一个单一的嵌套查询中做到这一点,以实现最终目标? – Dnaiel

+0

@Uueerdo更新了答案感谢您的输入.. –

相关问题