我有一个图书目录数据库。每本书可以有一个或多个作者。示例:
约翰·雷德 (John Red) 的书#1
弗雷德·格林和史蒂夫·布鲁的书#2
本·布朗的书#3
文章表:
id | 标题 |
---|---|
1 | 书1 |
2 | 书2 |
3 | 书3 |
作者表:
id | 姓氏 | 名字 |
---|---|---|
1 | 红色 | 约翰 |
2 | 绿色 | 弗雷德 |
3 | 蓝色 | 史蒂夫 |
4 | 棕色 | 本 |
AUTHORS_ARTICLES 表:
id_作者 | id_文章 |
---|---|
1 | 1 |
2 | 2 |
3 | 2 |
4 | 3 |
我需要检索书籍的详细信息,按作者的字母顺序排序。
我正在使用以下查询:
SELECT DISTINCT a.*
FROM articles a
LEFT OUTER JOIN authors_articles aa ON a.id = aa.id_article
LEFT OUTER JOIN authors au ON aa.id_author = au.id
ORDER BY au.surname ASC, au.name ASC
问题在于书籍并不总是按作者姓氏/姓名的字母顺序排序:当一本书有两个或多个作者时,出现在链接表(authors_articles)中的第一个作者将是从查询返回的作者,这不一定是按字母顺序排列的第一个。尽管如此,它仍将被查询末尾的 ORDER BY 子句使用,从而导致记录顺序错误。
我当前查询的结果是:
id | 标题 |
---|---|
3 | 书3 |
2 | 书2 |
1 | 书1 |
请注意,Brown 的书排在第一位,即使 Book2 的作者是 Green AND Blue。
我需要将它们列为 Book2、Book3 和 Book1。
任何帮助将不胜感激。
您需要先找到每本书的第一位作者,然后才能执行订单。可以使用一个简单的
row_number
查询来实现:
with cte as (
select
articles.*,
authors.surname,
authors.name,
row_number() over (
partition by articles.id
order by authors.surname, authors.name
) as rn
from articles
left join authors_articles on articles.id = authors_articles.id_article
left join authors on authors_articles.id_author = authors.id
)
select *
from cte
where rn = 1
order by surname, name