How to join only one row in joined table with postgres?

后端 未结 7 502
清歌不尽
清歌不尽 2021-01-31 01:31

I have the following schema:

CREATE TABLE author (
    id   integer
  , name varchar(255)
);
CREATE TABLE book (
    id        integer
  , author_id integer
  ,          


        
7条回答
  •  一整个雨季
    2021-01-31 02:24

    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
    

    Check distinct on

    SELECT DISTINCT ON ( expression [, ...] ) keeps only the first row of each set of rows where the given expressions evaluate to equal. The DISTINCT ON expressions are interpreted using the same rules as for ORDER BY (see above). Note that the "first row" of each set is unpredictable unless ORDER BY is used to ensure that the desired row appears first.

    With distinct on it is necessary to include the "distinct" columns in the order by. If that is not the order you want then you need to wrap the query and reorder

    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_book
    order by authors_with_first_book.name
    

    Another solution is to use a window function as in Lennart's answer. And another very generic one is this

    select 
        book.id, author.id, author.name, book.title as last_book
    from
        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
    

提交回复
热议问题