Mysql 如何优化此查询以避免重复获取重复信息
假设我有两张桌子,作者和书。每个作者可以有多本书,由图书表的authorId列标识,该列链接到作者表的id字段 我想获取具有特定类别Id的所有书籍,对于每本书,我想获得作者的姓名和照片url,以显示在书名旁边 因此,我进行如下查询:Mysql 如何优化此查询以避免重复获取重复信息,mysql,sql,database,distinct,one-to-many,Mysql,Sql,Database,Distinct,One To Many,假设我有两张桌子,作者和书。每个作者可以有多本书,由图书表的authorId列标识,该列链接到作者表的id字段 我想获取具有特定类别Id的所有书籍,对于每本书,我想获得作者的姓名和照片url,以显示在书名旁边 因此,我进行如下查询: SELECT author.name, author.photoUrl, book.title FROM author, book WHERE book.categoryId = '3' AND author.id = book.authorId
SELECT author.name, author.photoUrl, book.title
FROM author, book
WHERE book.categoryId = '3' AND author.id = book.authorId
问题是,如果一个作者在这个类别中有多本书怎么办?(例如,一位小说作家写了多部小说)。在这种情况下,是否会为每一行分别获取作者信息,从而获取重复信息,或者是否有任何方法,例如使用
DISTINCT
,以便只获取一次作者信息?首先,应使用标准联接语法:
SELECT author.name, author.photoUrl, book.title
FROM author join
book
on author.id = book.authorId
WHERE book.categoryId = '3'
您所称的“重复”信息正是SQL在联接中所做的。这没有问题。如果您给出了希望返回的内容的示例,那么可能有一种方法可以减少数据量
我突然想到,你可能想要一个作者的图书列表,作为一个分隔的列表。在这种情况下,请尝试以下方法:
SELECT author.name, author.photoUrl,
group_concat(book.title separator ', ') as books
FROM author join
book
on author.id = book.authorId
WHERE book.categoryId = '3'
group by author.name, author.photoUrl
首先,应使用标准联接语法:
SELECT author.name, author.photoUrl, book.title
FROM author join
book
on author.id = book.authorId
WHERE book.categoryId = '3'
您所称的“重复”信息正是SQL在联接中所做的。这没有问题。如果您给出了希望返回的内容的示例,那么可能有一种方法可以减少数据量
我突然想到,你可能想要一个作者的图书列表,作为一个分隔的列表。在这种情况下,请尝试以下方法:
SELECT author.name, author.photoUrl,
group_concat(book.title separator ', ') as books
FROM author join
book
on author.id = book.authorId
WHERE book.categoryId = '3'
group by author.name, author.photoUrl
您可以使用:
这将获取给定作者的所有标题,并将其作为逗号分隔的字符串返回。您可以使用:
这将获取给定作者的所有标题,并将其作为逗号分隔的字符串返回。是的,它将返回作者的重复标题,但我认为这不是问题
另一种方法是使用两个查询,一个用于书籍,一个用于作者,然后在代码中设置
数据集
或使用词典
)上的结果之间的关系
书
作者
SELECT
author.Id,
author.name,
author.photoUrl
FROM
author
WHERE
EXISTS(
SELECT NULL
FROM book
WHERE
book.categoryId = '3' AND
author.id = book.authorId
)
是的,它会返回作者的副本,但我不认为这是一个问题
另一种方法是使用两个查询,一个用于书籍,一个用于作者,然后在代码中设置
数据集
或使用词典
)上的结果之间的关系
书
作者
SELECT
author.Id,
author.name,
author.photoUrl
FROM
author
WHERE
EXISTS(
SELECT NULL
FROM book
WHERE
book.categoryId = '3' AND
author.id = book.authorId
)
您的原始查询(已修复):
完全按照您的要求执行:它将为类别3中的每本书返回一行,以及作者的姓名和照片URL
可以将其分解为两个结果集:
--
-- retrieve category 3 books
--
select *
from book b
where b.category = 3
--
-- retrieve related author data
--
select *
from author a
where exists ( select *
from book b
where b.authorId = a.id
and b.category = 3
)
现在取决于你如何根据作者来匹配每本书,不管你如何选择。第一个结果集应该包含作者的主键;第二个是author表的外键。原始查询(已修复):
完全按照您的要求执行:它将为类别3中的每本书返回一行,以及作者的姓名和照片URL
可以将其分解为两个结果集:
--
-- retrieve category 3 books
--
select *
from book b
where b.category = 3
--
-- retrieve related author data
--
select *
from author a
where exists ( select *
from book b
where b.authorId = a.id
and b.category = 3
)
现在取决于你如何根据作者来匹配每本书,不管你如何选择。第一个结果集应该包含作者的主键;第二个是author表的外键。请向我们展示一个输出与请求的输出的示例。为什么要使用隐式联接的SQL反模式?@HLGEM它与其他联接相比是否存在性能问题?o但更难维护(特别是如果以后需要转换为左联接)更可能发生意外的交叉连接。这种语法在20年前被取代,如果C#很久以前就存在,你会使用很久以前被替换的C#代码吗?@ClickUpvote:你试图解决的问题是什么?请给我们展示一个输出与请求输出的示例。为什么要使用隐式联接的SQL反模式?@HLGEM它与其他联接相比是否存在性能问题?o,但是它更难维护(特别是如果您以后需要转换为左连接),并且更可能发生意外的交叉连接。这种语法在20年前就被取代了,如果C早就存在了,你会使用这么久以前就被取代的C代码吗?@ClickUpvote:你想解决的问题是什么?为你鼓励使用隐式连接感到羞耻。“我们不应该鼓励人们使用拙劣的技术。”天哪,有头牛吗?为什么使用隐式连接会使一个人比希特勒糟糕一百万倍?我几乎没有说过这一点,顺便说一句,我不是,也从来不是一个男人。但是使用隐式连接是公认的sql反模式,我们应该向人们展示正确的方法。我将始终否决任何在答案中使用一个选项的人。@dbaseman:如果您想使用MySQL“技巧”和
groupby
,那么您应该groupby author.id
,而不是author.name。可能有同名(但ID不同)的作者。@dbaseman老实说,整个事件都是因为你对评论的反应而爆发的。希特勒真的不是一个恰当的比喻,以“你的耻辱”的评论(我同意,这本来可以加上多一点机智)。话虽如此,显式连接在ANSI-92中是“标准”的,有利于隐式连接。这里有一条08年的SO线索,你可能会觉得有趣。你鼓励使用隐式联接真是太丢脸了。“我们不应该鼓励人们使用拙劣的技术。”天哪,有头牛吗?为什么使用隐式连接会使一个人比希特勒糟糕一百万倍?我几乎没有说过这一点,顺便说一句,我不是,也从来不是一个男人。但是使用隐式连接是公认的sql反模式,我们应该向人们展示正确的方法。我将始终否决任何在答案中使用一个选项的人。@dbaseman:如果您想在分组方式中使用MySQL“技巧”,则