gpt4 book ai didi

sql - 如何使用 postgres 在连接表中只连接一行?

转载 作者:行者123 更新时间:2023-11-29 11:06:56 24 4
gpt4 key购买 nike

我有以下架构:

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

我希望每个作者都有他们的最后一本书:

SELECT book.id, author.id, author.name, book.title as last_book
FROM author
JOIN book book ON book.author_id = author.id

GROUP BY author.id
ORDER BY book.id ASC

显然你可以在 mysql 中做到这一点:Join two tables in MySQL, returning just one row from the second table .

但是 postgres 给出了这个错误:

ERROR: column "book.id" must appear in the GROUP BY clause or be used in an aggregate function: SELECT book.id, author.id, author.name, book.title as last_book FROM author JOIN book book ON book.author_id = author.id GROUP BY author.id ORDER BY book.id ASC

It's because :

When GROUP BY is present, it is not valid for the SELECT list expressions to refer to ungrouped columns except within aggregate functions, since there would be more than one possible value to return for an ungrouped column.

我如何向 postgres 指定:“在连接表中按 joined_table.id 排序时,只给我最后一行?”


编辑:有了这些数据:

INSERT INTO author (id, name) VALUES
(1, 'Bob')
, (2, 'David')
, (3, 'John');

INSERT INTO book (id, author_id, title, rating) VALUES
(1, 1, '1st book from bob', 5)
, (2, 1, '2nd book from bob', 6)
, (3, 1, '3rd book from bob', 7)
, (4, 2, '1st book from David', 6)
, (5, 2, '2nd book from David', 6);

我应该看到:

book_id author_id name    last_book
3 1 "Bob" "3rd book from bob"
5 2 "David" "2nd book from David"

最佳答案

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

检查 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.

使用 distinct on 时,有必要在 order by 中包含“distinct”列。如果这不是您想要的顺序,那么您需要包装查询并重新排序

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

另一种解决方案是使用 Lennart 的回答中的窗口函数。另一个非常通用的是这个

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

关于sql - 如何使用 postgres 在连接表中只连接一行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24042359/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com