我需要一些复杂的SQL查询帮助。这是我的设置:有两个表,一个是作者,另一个是书。 books表包含一个名为“author”的字段,其中包含作者的id。如果一本书有多个作者,那么“作者”字段将包含由“;”分隔的所有作者ID (像2; 34; 234)。
在网站上,我必须列出作者撰写的所有书籍。如果只有一位作者,那很简单,但我如何才能获得那些我感兴趣的作者是第二作者还是第三作者?
非常感谢。
答案 0 :(得分:2)
这是坏表设计的一个例子。理想情况下,您将有3个表books
,books2authors
,authors
books2authors
将保留book_id
和author_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;
这是恶劣设计给出的恶梦的一个很好的例子。查询应该可以工作,但它总是执行全表扫描(当表变大时非常慢)。