|
我有以下结构:
( R. u: Q/ ], G: Y# O; l7 d6 d/ ZCREATE TABLE author id integer ,name varchar(255));CREATE TABLE book id integer ,author_id integer ,title varchar(255) ,rating integer);我希望每个作者都能读到最后一本书:# o5 R- u$ N) \7 w5 E
SELECT book.id,author.id,author.name,book.title as last_bookFROM authorJOIN book book ON book.author_id = author.idGROUP BY author.idORDER BY book.id ASC显然,你可以在那里mysql执行此操作:在MySQL连接两个表,只从第二个表返回一行。
! G( F. z' U, s+ S- a9 q8 m+ _但是postgres给出这个错误:
- o2 M( e! v) m9 z) S错误:“ book.id必须出现列GROUP BY用于子句或聚合函数:SELECT
/ c6 [) @! _+ }9 E, [book.id,author.id,author.name,book.title为last_book FROM author JOIN book) ?: d! v3 ]2 Y- m
book on book.author_id = author.id GROUP BY author.id ORDER BY book.id ASC- A2 b s8 L3 s3 W7 ^- O; _
这是因为:
/ N, \' i8 o2 ^* o如果存在GROUP BY,则SELECT未分组列(聚合函数除外)不能引用列表表达式,因为未分组列将返回多个可能值。/ g2 x {) B3 B, I) h6 s% V' Z
我如何指定postgres:“仅joined_table.id在连接表中按顺序给我最后一行?
% v! c' }' l$ ^' l3 C! C) {编辑:使用此数据:
, b. L( k; `3 d- Q) U5 t, h1 V+ J a& dINSERT INTO author (id,name) VALUES (1,'Bob(二),David(3),John');INSERT INTO book (id,author_id,title,rating) VALUES 1、1、1、1st book from bob五、nd book from bob六、rd book from bob七、st book from David(、nd book from David',6);我应该看到:
1 x5 r" A% T- ?, ^$ o P9 \0 {book_id author_id name last_book3 3 1 "Bob" "3rd book from bob"5 2 "David" "2nd book from David" 1 G% z+ [$ ^1 T( P H! W/ T
解决方案: 0 B9 }" B+ u4 F) l
select distinct on (author.id) book.id,author.id,author.name,book.title as last_bookfrom author inner join book on book.author_id = author.idorder by author.id,book.id desc查看 distinct on
* y4 A! n" C; o" H$ qSELECT DISTINCT ON(expression [,…])每组行的第一行只保留给定表达式。ORDER# e7 o4 P- u* o. G( D4 ]
BY解释相同的规则DISTINCT ON表达式(请参见上面)。请注意,除非使用。ORDER# X2 a' c8 l$ p j# A
BY确保所需的行先出现,否则每一集的第一行都是不可预测的。
. e3 v+ `' W e S内容独特,有必要在其中添加独特列order by。如果不是你想要的顺序,你需要包装查询并重新排序; t- `$ o. x3 l8 L& ^% ]
select *from select distinct on (author.id) book.id,author.id,author.name,book.title as last_book from author inner join book on book.author_id = author.id order by author.id,book.id desc) authors_with_first_bookorder by authors_with_first_book.name另一种解决方案是使用Lennart答案中的窗口函数。另一个很常见的是8 q+ R" @5 i0 y' M5 b: p
select book.id,author.id,author.name,book.title as last_bookfrom book inner join ( select author.id as author_id,max(book.id) as book_id from author inner join book on author.id = book.author_id group by author.id ) s on s.book_id = book.id inner join author on book.author_id = author.id |
|