需要一些复杂的SQL查询的帮助

时间:2010-05-12 14:52:15

标签: mysql

我需要一些复杂的SQL查询帮助。这是我的设置:有两个表,一个是作者,另一个是书。 books表包含一个名为“author”的字段,其中包含作者的id。如果一本书有多个作者,那么“作者”字段将包含由“;”分隔的所有作者ID (像2; 34; 234)。

在网站上,我必须列出作者撰写的所有书籍。如果只有一位作者,那很简单,但我如何才能获得那些我感兴趣的作者是第二作者还是第三作者?

非常感谢。

5 个答案:

答案 0 :(得分:2)

这是坏表设计的一个例子。理想情况下,您将有3个表booksbooks2authorsauthors books2authors将保留book_idauthor_id,因此一本书可以拥有更多作者,您可以在SQL中轻松使用它们。

如果您无法更改设计,那么我会获取所有书籍,解析author_id字段,如果您只想获得第二位作者,请发出额外查询select * from authors where id = <second_author>得到你需要的信息。

答案 1 :(得分:1)

如果可以,请更改架构。尝试使用AuthorPosition查找表,如下所示:

BookID  AuthorID  AuthorPosition
1       1         1
1       2         2
1       4         3
2       3         1
2       1         2

然后,如果您需要第二位作者,则可以查询AuthorPosition = 2。

如果您无法更改架构,您可以获取所有书籍(甚至可以使用LIKE查询,但我不确定如何),然后在业务代码中解析您想要的作者。

答案 2 :(得分:1)

如果您无法更改架构以使用intersection表(例如BooksAuthors),那么以下内容应该有效:

...
where AuthorID = '42' 
    or AuthorID = '42;%' 
    or AuthorID = '%;42;%' 
    or AuthorID = '%;42'

这些子句中只有前两个可以使用索引,因此搜索除第一个之外的作者将会更慢。

答案 3 :(得分:0)

您可以更改数据库表吗?

您应该将书籍和作者ID放在他们自己的表格(连接表)中。

此表(可能称为book_author)只具有Books和Authors的ID,因此您可以执行以下查询:

select a.* from book b, book_author ba, author a
where 
    b.id == ba.book_id
    and
    a.id == ba.author_id
    and 
    b.id = 123;

返回ID为123的图书的所有作者。

答案 4 :(得分:0)

我建议你做一个小改动:更换;分隔符,(逗号)。 然后你可以这样做:

select b.*
from authors a
inner join books b on find_in_set(a.id, b.author) >0;

这是恶劣设计给出的恶梦的一个很好的例子。查询应该可以工作,但它总是执行全表扫描(当表变大时非常慢)。