检索结果时如何解决不明确的列名?
我的数据库中有两个表:
NEWS 表,其中列:
id
- 新闻 IDuser
- 作者的用户 ID)
USERS 表,其中列:
id 的用户 ID
-我想要执行此 SQL
SELECT * FROM news JOIN users ON news.user = user.id
:当我在 PHP 中获取结果时,我想通过 $row['column-name'] 获取关联数组并获取列名称
。 如何获取具有相同列名的新闻 ID 和用户 ID?
I have two tables in my database:
NEWS table with columns:
id
- the news iduser
- the user id of the author)
USERS table with columns:
id
- the user id
I want to execute this SQL:
SELECT * FROM news JOIN users ON news.user = user.id
When I get the results in PHP I would like to get associative array and get column names by $row['column-name']
. How do I get the news ID and the user ID, having the same column name?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
您可以为您选择的列设置别名:
You can set aliases for the columns that you are selecting:
您可以使用数字索引 (
$row[0]
) 或更好,在 MySQL 中使用AS
:SELECT *, user.id AS user_id FROM 。 ..
You can either use the numerical indices (
$row[0]
) or better, useAS
in the MySQL:SELECT *, user.id AS user_id FROM ...
我刚刚想通了这一点。 这可能是一个不好的做法,但在这种情况下它对我有用。
我是懒惰的人之一,不想使用表前缀来别名或写出每个列名。
您可以通过在 select 语句中使用
table_name.*
从特定表中选择所有列。当你有重复的列名时,mysql会从头到尾覆盖。 当再次遇到该列名时,第一个重复列名中的数据将被覆盖。 因此最后出现的重复列名获胜。
如果我连接 3 个表,每个表都包含重复的列名,则 select 语句中表的顺序将决定我从重复列获取哪些数据。
示例:
在上面的示例中,我获得的
dup
值将来自table3
。如果我希望
dup
成为table1
中的值怎么办?然后我需要这样做:
现在,
table1
排在最后,因此dup
的值将是 table1 中的值。我得到了我想要的 dup 值,而不必写出每一个奇怪的列,而且我仍然可以使用所有列。 耶!
我知道
dup
的值在所有 3 个表中应该相同,但是如果table3
没有dup
的匹配值怎么办? 那么在第一个示例中,dup
将是空白,这将是一个糟糕的结果。I just figured this out. It's probably a bad practice but it worked for me in this case.
I am one of the lazy people who doesn't want to alias or write out every column name with a table prefix.
You can select all of the columns from a specific table by using
table_name.*
in your select statement.When you have duplicated column names, mysql will overwrite from first to last. The data from the first duplicated column name will be overwritten when it encounters that column name again. So the duplicate column name that comes in last wins.
If I am joining 3 tables, each containing a duplicated column name, the order of the tables in the select statement will determine what data I am getting for the duplicate column.
Example:
In the example above, the value of
dup
I get will be fromtable3
.What if I want
dup
to be the value fromtable1
?Then I need to do this:
Now,
table1
comes last, so the value ofdup
will be the value from table1.I got the value I wanted for
dup
without having to write out every single freaking column and I still get all of the columns to work with. Yay!I know the value of
dup
should be the same in all 3 tables, but what iftable3
doesn't have a matching value fordup
? Thendup
would be blank in the first example, and that would be a bummer.@杰森。 你是对的,除了 php 是罪魁祸首而不是 mysql 之外。 如果您将
JOIN
放入 Mysql Workbench,您将得到三列名称完全相同的列(每个表一个),但数据不同(如果有的话,有些列将为 null该表与JOIN
不匹配)。在 php 中,如果您在
mysql_fetch_array()
中使用MYSQL_NUM
那么您将获得所有列。 问题是当您将 mysql_fetch_array() 与 MYSQL_ASSOC 一起使用时。 然后,在该函数内部,php 正在构建返回值,如下所示:稍后......
因此
您将仅获得 table3 中的值。 问题是 mysql 的结果集可以包含同名的列,但 php 中的关联数组不允许数组中出现重复的键。 当数据保存在关联数组中时,在 php 中,一些信息会悄然丢失......
@Jason. You are correct except that php is the culprit and not mysql. If you put your
JOIN
in Mysql Workbench you will get three columns with the exact same name (one for each table) but not with the same data (some will benull
if that table has no match for theJOIN
).In php if you use
MYSQL_NUM
inmysql_fetch_array()
then you will get all columns. The problem is when you usemysql_fetch_array()
withMYSQL_ASSOC
. Then, inside that function, php is building the return value like so:and later on...
...
So you will get only the value from table3. The problem is that a result set from mysql can contain columns with the same name but associative arrays in php don't allow duplicate keys in arrays. When the data is saved in associative arrays, in php, some information is silently lost...
另一个提示:如果你想要更干净的 PHP 代码,你可以在数据库中创建一个 VIEW,例如
:
在 PHP 中:
Another tip: if you want to have cleaner PHP code, you can create a VIEW in the database, e.g.
For example:
In PHP:
您可以执行类似的操作
,然后
$row['news_id']
将是新闻 id,$row['user_id']
将是用户 idYou can do something like
And then
$row['news_id']
will be the news id and$row['user_id']
will be the user id我对动态表也有同样的问题。 (假定表具有能够连接的 id,但对其余字段没有任何假设。)在这种情况下,您事先不知道别名。
在这种情况下,您可以首先获取所有动态表的表列名称:
其中 $zendDbInstance 是 Zend_Db 的实例,或者您可以使用此处的函数之一来不依赖 Zend php pdo:获取表的列名
然后对于所有动态表,您可以获取别名并使用$tableName.* 对于那些不需要别名的人:
您可以将整个过程包装到一个通用函数中,并且只需拥有更清晰的代码,或者如果您愿意的话可以变得更加懒惰:)
I had this same issue with dynamic tables. (Tables that are assumed to have an id to be able to join but without any assumption for the rest of the fields.) In this case you don't know the aliases before hand.
In such cases you can first get the table column names for all dynamic tables:
Where $zendDbInstance is an instance of Zend_Db or you can use one of the functions here to not rely on Zend php pdo: get the columns name of a table
Then for all dynamic tables you can get the aliases and use $tableName.* for the ones you don't need aliases:
You can wrap this whole process up into one generic function and just have cleaner code or get more lazy if you wish :)
使用 PDO 进行数据库交互时,可以使用 PDO::FETCH_NAMED 获取模式,该模式可以帮助解决问题:
When using PDO for a database interacttion, one can use the PDO::FETCH_NAMED fetch mode that could help to resolve the issue:
如果您不想使用别名,也可以在表名前添加前缀。
这样您就可以更好地自动生成查询。 另外,最好不要使用 select * (这显然比仅选择您需要的字段慢需要
此外,仅明确命名您想要的字段。
If you don't feel like aliassing you can also just prefix the tablenames.
This way you can better automate generation of your queries. Also, it's a best-practice to not use select * (it is obviously slower than just selecting the fields you need
Furthermore, only explicitly name the fields you want to have.
这是上述问题的答案,既简单又适用于返回的 JSON 结果。 当您使用 SELECT * 时,SQL 查询会自动为每个相同字段名称的实例添加表名称前缀,但将结果发送回网页时采用 JSON 编码,会忽略具有重复名称的字段的值,而是返回 NULL 值。
确切地说,它的作用是包含重复字段名称的第一个实例,但使其值为 NULL。 字段名称的第二个实例(在另一个表中)被完全省略,包括字段名称和值。 但是,当您直接在数据库上测试查询时(例如使用 Navicat),所有字段都会在结果集中返回。 只有当您接下来对该结果进行 JSON 编码时,它们才会具有 NULL 值,并且后续的重复名称会被完全省略。
因此,解决该问题的一个简单方法是首先执行 SELECT *,然后使用重复项的别名字段。 下面是一个示例,其中两个表具有相同名称的 site_name 字段。
现在,在解码后的 JSON 中,您可以使用字段 wo_site_name 并且它有一个值。 在这种情况下,站点名称具有特殊字符,例如撇号和单引号,因此在最初保存时进行编码,在使用数据库结果时进行解码。
您必须始终将 * 放在 SELECT 语句的前面,但在其后面可以包含任意数量的命名列和别名列,因为重复选择列不会出现问题。
Here's an answer to the above, that's both simple and also works with JSON results being returned. While the SQL query will automatically prefix table names to each instance of identical field names when you use SELECT *, JSON encoding of the result to send back to the webpage, ignores the values of those fields with a duplicate name and instead returns a NULL value.
Precisely what it does is include the first instance of the duplicated field name, but makes its value NULL. And the second instance of the field name (in the other table) is omitted entirely, both field name and value. But, when you test the query directly on the database (such as using Navicat), all fields are returned in the result set. It's only when you next do JSON encoding of that result, do they have NULL values and subsequent duplicate names are omitted entirely.
So, an easy way to fix that problem is to first do a SELECT *, then follow with aliased fields for the duplicates. Here's an example, where both tables have identically named site_name fields.
Now in the decoded JSON, you can use the field wo_site_name and it has a value. In this case, site names have special characters such as apostrophes and single quotes, hence the encoding when originally saving, and the decoding when using the result from the database.
You must always put the * first in the SELECT statement, but after it you can include as many named and aliased columns as you want, as repeatedly selecting a column causes no problem.
有两种方法:
使用别名; 在此方法中,您为各个列指定新的唯一名称 (ALIAS),然后在 PHP 检索中使用它们。
例如
然后用 PHP 获取结果:
使用位置位置或结果集列索引; 在此,数组位置用于引用重复的列名称。 由于它们出现在不同的位置,因此将使用的索引号始终是唯一的。
然而,索引定位编号从0开始。例如
然后用 PHP 获取结果:
There are two approaches:
Using aliases; in this method you give new unique names (ALIAS) to the various columns and then use them in the PHP retrieval.
e.g.
and then fetch the results in PHP:
Using place position or resultset column index; in this, the array positions are used to reference the duplicated column names. Since they appear at different positions, the index numbers that will be used is always unique.
However, the index positioning numbers begins at 0. e.g.
and then fetch the results in PHP: