Pax*_*Pax 5 postgresql join array coalesce sqlalchemy
当特定图书馆中没有书籍数据时,就会出现问题。考虑以下工作场景。
桌子 library
--------------------------------
| id | name | owner |
--------------------------------
| 1 | ABC | A |
| 2 | DEF | D |
| 3 | GHI | G |
--------------------------------
Run Code Online (Sandbox Code Playgroud)
桌子 books
--------------------------------
| id | title | library |
--------------------------------
| a | xxx | 1 |
| b | yyy | 1 |
| c | zzz | 2 |
--------------------------------
Run Code Online (Sandbox Code Playgroud)
现在,当我进行如下查询时:
SELECT library.name, array_agg(b.title) AS book_list FROM library,
(SELECT title FROM books WHERE books.library = :library_no) as b
WHERE library.id = :library_no GROUP BY library.id
Run Code Online (Sandbox Code Playgroud)
该查询为库 1 和 2 生成输出,但不为库 3 生成输出。为什么以及如何解决此问题?(在没有图书馆书籍的情况下生成一个空列表)
所需输出:
----------------------
| name | book_list |
----------------------
| GHI | {} | # or {null}
-----------------------
Run Code Online (Sandbox Code Playgroud)
我什至试过coalesce如下:
SELECT library.name, coalesce(array_agg(b.title), ARRAY[]::VARCHAR[]) AS book_list FROM library,
(SELECT title FROM books WHERE books.library = :library_no) as b
WHERE library.id = :library_no GROUP BY library.id
Run Code Online (Sandbox Code Playgroud)
Postgres 版本:12
ALEFT JOIN可以解决它,就像Laurenz提供的那样。
但我建议在LATERAL子查询中使用 ARRAY 构造函数:
SELECT l.name, b.book_list
FROM library l
CROSS JOIN LATERAL (
SELECT ARRAY(
SELECT title
FROM books
WHERE library = l.id
)
) b(book_list)
WHERE l.id = :library_no;
Run Code Online (Sandbox Code Playgroud)
这样,您不需要在外部查询级别聚合,也不需要在GROUP BY那里聚合。
您也不需要COALESCE,因为空结果上的 ARRAY 构造函数已经生成了一个空数组 ( {})。
对于一个小的选择,它应该更快library- 显然查询获得单个给定库的结果。
此外,您只需要:library_no像演示一样在一个地方使用变量。
关于LATERAL加入:
关于 ARRAY 构造函数:
你需要一个左连接:
... FROM library
LEFT JOIN books ON library.id = books.library
Run Code Online (Sandbox Code Playgroud)
然后你也会得到没有书的图书馆。
| 归档时间: |
|
| 查看次数: |
312 次 |
| 最近记录: |