Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何优化此查询以避免重复获取重复信息_Mysql_Sql_Database_Distinct_One To Many - Fatal编程技术网

Mysql 如何优化此查询以避免重复获取重复信息

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

假设我有两张桌子,作者和书。每个作者可以有多本书,由图书表的authorId列标识,该列链接到作者表的id字段

我想获取具有特定类别Id的所有书籍,对于每本书,我想获得作者的姓名和照片url,以显示在书名旁边

因此,我进行如下查询:

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“技巧”,则