PHP和MYSQL:如何解决JOIN操作中不明确的列名?

我在我的数据库中有两个表:

新闻('id' – 新闻ID,'用户' – 作者的用户ID)

USERS('id' – 用户ID)

我想做一个SELECT * FROM news JOIN users ON news.user = user.id ,现在当我在PHP中得到的结果是这样的:

$row = mysql_fetch_array($result) ,并获得列名$row['column-name'] …我如何获得新闻ID和用户ID,具有相同的列名?

更新:谢谢大家的快速答案。 别名似乎是最好的解决scheme。

您可以为要select的列设置别名:

 $query = 'SELECT news.id AS newsId, user.id AS userId, [OTHER FIELDS HERE] FROM news JOIN users ON news.user = user.id' 

您可以使用数字索引( $row[0] )或更好,在MySQL中使用AS

SELECT *, user.id AS user_id FROM ...

我只是明白了这一点。 这可能是一个不好的做法,但在这种情况下对我很有帮助。

我是懒惰的人之一,不希望用表前缀别名或写出每个列名。

您可以通过在select语句中使用table_name.*来select特定表中的所有列。

当你有重复的列名时,mysql会从头到尾进行覆盖。 当第一个重复列名的数据再次遇到该列名时将被覆盖。 所以上次获得的重复的列名称。

如果我join了3个表,每个表都包含一个重复的列名,select语句中表的顺序将决定我得到的重复列的数据。

例:

 SELECT table1.* , table2.* , table3.* FROM table1 LEFT JOIN table2 ON table1.dup = table2.dup LEFT JOIN table3 ON table2.dup = table3.dup; 

在上面的例子中,我得到的dup的值将来自table3

如果我想duptable1的值呢?

那么我需要这样做:

 SELECT table3.* , table2.* , table1.* FROM table1 LEFT JOIN table2 ON table1.dup = table2.dup LEFT JOIN table3 ON table2.dup = table3.dup; 

现在, table1最后,所以dup的值将是table1的值。

我得到了我想要的dup值,而不必写出每一个吓人的列,我仍然得到所有的列工作。 好极了!

我知道dup的值应该在所有3个表中都是相同的,但是如果table3没有dup的匹配值呢? 那么在第一个例子中dup会是空白的,那将是一个无赖。

另一个提示:如果你想有更干净的PHP代码,你可以在数据库中创build一个VIEW,例如

例如:

 CREATE VIEW view_news AS SELECT news.id news_id, user.id user_id, user.name user_name, [ OTHER FIELDS ] FROM news, users WHERE news.user_id = user.id; 

在PHP中:

 $sql = "SELECT * FROM view_news"; 

你可以做类似的事情

 SELECT news.id as news_id, user.id as user_id .... 

然后$row['news_id']将是新闻ID, $row['user_id']将是用户ID

@Jason。 你是正确的,除了PHP是罪魁祸首,而不是MySQL。 如果你把JOIN放在Mysql Workbench中,你会得到三个名字完全相同的列(每个表有一个),但是没有相同的数据(如果这个表没有JOIN匹配的话,一些将是null的)。

在php中,如果您在mysql_fetch_array()使用MYSQL_NUM ,那么您将获得所有列。 问题是当你使用mysql_fetch_array()MYSQL_ASSOC 。 然后,在这个函数里面,php正在创build如下的返回值:

 $row['dup'] = [value from table1] 

后来…

 $row['dup'] = [value from table2] 

 $row['dup'] = [value from table3] 

所以你只会得到table3的值。 问题是从MySQL的结果集可以包含具有相同名称的列,但在PHP中的关联数组不允许在数组中的重复键。 当数据保存在关联数组中时,在PHP中,一些信息将悄悄丢失…

我对dynamic表有同样的问题。 (假设有一个表可以join,但是没有任何其他字段的假设)。在这种情况下,你并不知道别名。

在这种情况下,您可以首先获取所有dynamic表的表列名称:

 $tblFields = array_keys($zendDbInstance->describeTable($tableName)); 

其中$ zendDbInstance是Zend_Db的一个实例,或者你可以在这里使用其中的一个函数来不依赖Zend php pdo:获取表的列名

那么对于所有的dynamic表,你可以得到别名,并使用$ tableName。*为你不需要别名:

 $aliases = ""; foreach($tblKeys as $field) $aliases .= $tableName . '.' . $field . ' AS ' . $tableName . '_' . $field . ',' ; $aliases = trim(',', $aliases); 

你可以将整个过程包装成一个generics函数,只需要更干净的代码或者如果你愿意的话可以得到更多的懒惰:)

如果你不喜欢别名,你也可以在表名前加上。

这样你可以更好地自动生成你的查询。 另外,最好不要使用select *(这显然比只select你需要的字段慢)而且,只显式地命名你想要的字段。

 SELECT news.id, news.title, news.author, news.posted, users.id, users.name, users.registered FROM news LEFT JOIN users ON news.user = user.id 

有两种方法:

1.使用别名; 在这个方法中,你给各个列赋予新的唯一名称(ALIAS),然后在PHP检索中使用它们。

例如。

SQL $ sql = SELECT student_id FEES_LINK,student_class CLASS_LINK from students_fee_tbl LE​​FT JOIN student_class_tbl ON students_fee_tbl.student_id = student_class_tbl.student_id

PHP $查询= mysql_fetch_assoc($ sql); / /如果使用旧的方法

$ query = PDO->fetchAll(); //不是确切的语法,但这是目前的方法

 foreach($query as $q){ echo $q['FEES_LINK']; } 

2。

使用地点位置或结果集列索引; 在这里,数组的位置被用来引用重复的列名。 由于它们出现在不同的位置,所使用的索引号总是唯一的。 但是,索引定位编号从0开始。

例如。

$ sql = SELECT students_fee_tbl中的student_id,student_class LEFT JOIN student_class_tbl ON students_fee_tbl.student_id = student_class_tbl.student_id

PHP

$ query = mysql_fetch_assoc($ sql); //如果使用旧的方法

$查询= PDO-> fetchAll(); / /不是确切的语法,但这是目前的做法

 foreach($query as $q){ echo $q[0]; } 

这两件作品。

希望它有帮助。 🙂