回答

收藏

如何使用Postgres联接表中只有一行?

技术问答 技术问答 458 人阅读 | 0 人回复 | 2023-09-14

我有以下结构:! U2 k' D  `: S  |" C# L0 Y
CREATE TABLE author  id   integer  ,name varchar(255));CREATE TABLE book  id        integer  ,author_id integer  ,title     varchar(255)  ,rating    integer);我希望每个作者都能读到最后一本书:
( D& k0 U/ X; s- Z8 h% oSELECT 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连接两个表,只从第二个表返回一行。
7 v; S8 D/ V& [' W8 i# v但是postgres给出这个错误:) g+ o  u" z: p( {# V) E6 d5 ?9 a
错误:“ book.id必须出现列GROUP BY用于子句或聚合函数:SELECT
, \/ G. t  ]$ w+ m& y3 S# m9 Nbook.id,author.id,author.name,book.title为last_book FROM author JOIN book
4 t/ J! k) o( T$ J( t# _1 a3 zbook on book.author_id = author.id GROUP BY author.id ORDER BY book.id ASC
) H! r1 E, H2 [  z0 ?  _
这是因为:
) I& j1 p7 s. V# i如果存在GROUP BY,则SELECT未分组列(聚合函数除外)不能引用列表表达式,因为未分组列将返回多个可能值。
0 A; F" M( n  G% H4 F. d( G
我如何指定postgres:“仅joined_table.id在连接表中按顺序给我最后一行?# e2 j$ u4 R3 P0 A# B/ L! j0 S
编辑:使用此数据:4 `1 y& S2 \( v
INSERT 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);我应该看到:
2 F- M. R1 k% q0 Ibook_id author_id name    last_book3 3     1                              "Bob"   "3rd book from bob"5        2                       "David" "2nd book from David"                - H, {2 r3 |) r# H2 S' w4 d/ Y
    解决方案:                                                               
+ s2 q0 E5 s, y                                                                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" N, k  N6 B9 m
SELECT DISTINCT ON(expression [,…])每组行的第一行只保留给定表达式。ORDER2 A! M: Q+ W5 a
BY解释相同的规则DISTINCT ON表达式(请参见上面)。请注意,除非使用。ORDER
6 e# ~' l! {; HBY确保所需的行先出现,否则每一集的第一行都是不可预测的。
6 j. y3 h* Z# y; L9 Q! ]3 h内容独特,有必要在其中添加独特列order by。如果不是你想要的顺序,你需要包装查询并重新排序( O5 \5 A/ h* D% O7 i( _& A
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答案中的窗口函数。另一个很常见的是! D+ G/ m( ?8 S+ r$ _
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
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则