将第二个表中的第二个(条件)结果添加到 SQL 查询
Posted
技术标签:
【中文标题】将第二个表中的第二个(条件)结果添加到 SQL 查询【英文标题】:Add second (conditional) result from second table to SQL query 【发布时间】:2020-02-07 20:03:06 【问题描述】:我在一个数据库中有两个表。一个使用索引 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 (author2) 以及主 ID 从作者表中提取,以便在每一行中添加 name2 和 status2 字段。我只是看不到该怎么做...
需要注意的是,虽然主要作者 ID 字段总是非零,但如果没有第二个 ID,则 author2 字段将包含零,并且作者表中没有作者 ID 0,因此任何解决方案都需要通过在这些字段中提供空字符串或其他内容来处理 0 的 author2 ID,而不是给出错误。 (或者更不优雅的是,我想可以将带有空数据的虚拟作者 ID 0 添加到作者表中。)
任何人都可以建议一个可以避免此类二次查询的修改后的原始查询吗?
【问题讨论】:
样本数据和期望的结果会有所帮助。 【参考方案1】:永远不要在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
【讨论】:
我从他的描述中假设 [status] 与locked2 相同。 "每行都添加了 name2 和 locked2 字段。" 这看起来很棒。谢谢戈登!我正在管理一个最初由其他人编写的大型代码库,并且我假设(因为它工作正常)他的语法很好。感谢您指出 LEFT JOIN 的这种用法,它将改进我的很多代码。 ;) 我只是检查我是否可以使用:a2.name AS name2、a2.status AS status2 等来获取行返回中的不同字段。并且它不会抱怨连接表中没有 ID 0。【参考方案2】:Gordon Linoff 的答案看起来像您所需要的。
我会将此添加为评论,但消息太长...
我只是有一个关于数据库规范化的问题/评论。会有作者3的实例吗?如果是这样,那么您可能应该有一个 ArticleAuthor 表。由于您无论如何都在重建代码,这可能是一个值得考虑的改进。
我不知道您存储的信息的名称和数据类型,所以这是我建议的结构的原始示例。
Table Article
ArticleID
ArticleData...
Table Author
AuthorID
AuthorName
AuthorStatus
Table ArticleAuthor
ArticleID
AuthorID
如果状态依赖于作者文章组合,那么 AuthorStatus 将像这样移动到 ArticleAuthor 表中。
Table ArticleAuthor
ArticleID
AuthorID
Status
【讨论】:
感谢您的建议。目前没有添加第三作者的计划……哈哈!以上是关于将第二个表中的第二个(条件)结果添加到 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章
如何在 EF / EF Core 中的第二个表上实现具有某些条件的左连接?