我在数据库中有两个表。一个使用索引ID存储用户的名称/详细信息;其他存储他们编写的文章,仅保留用户的ID作为参考(字段author)。到目前为止很简单。我可以轻松地查询文章列表,并在查询中包含对用户名和状态的请求:
SELECT a.name, a.status, s.* FROM articles s, author a WHERE s.author=a.id
问题出在我偶尔获得第二作者功劳时,在字段[[author2中引用。到现在为止,我一直在做我认为遍历结果时效率非常低的第二个查询,只是从表中获得第二个作者的姓名和状态(伪代码):
while ( fetch a row ) {
if (author2 != 0) {
query("SELECT name, status FROM author WHERE id=author2") }
etc. }
尽管此方法在PHP / MySQL中运行良好(即使笨拙),但我不得不升级到PHP7 / PDO,但我想获得无缓冲查询的好处,因此此嵌套查询将不起作用。显然,一种简单的解决方案是先对PDO-> fetchALL()的整个结果进行处理,然后再对foreach循环中的所有结果行进行迭代,并对每行进行这些额外的查询。)和主ID从author表中提取数据,这样可以name2和locked2字段添加到每一行。我只是看不到该怎么做...应注意,虽然主要作者ID字段始终为非零,但如果没有第二个ID,并且在作者表中没有作者ID 0,那么author2字段将包含零,因此任何解决方案都需要通过在这些字段中提供空字符串或某些内容(而不是给出错误)来处理author2 ID为0。 (或者,可以说,可以将一个具有空数据的伪作者ID 0添加到作者表中,这不是很优雅)。但是将第二个数据以某种方式合并到主查询中会更加有效,使用第二个ID(
author2
任何人都可以提出可以避免此类二次查询的经过修订的原始查询吗?
Never在FROM
子句中使用逗号。 总是使用正确的,显式的标准 JOIN
语法。
LEFT JOIN
:SELECT s.*, a1.name, a1.status, a2.name, a2.status
FROM articles s LEFT JOIN
author a1
ON s.author = a1.id LEFT JOIN
author a2
ON s.author2 = a2.id