postgresql - 创建一个 PostgreSQL 函数,该函数成为一个表的公式字段,从其他表中检索相关数据
问题描述
上面的示例可以在 SQL Server 上完成。它是一个函数,在另一个表上执行计算,同时获取当前表字段 Id 以列出来自其他表的数据,返回单个值。
问题:如何用 PostgreSQL 做确切的事情
SELECT TOP(5) * FROM Artists;
+------------+------------------+--------------+-------------+
| ArtistId | ArtistName | ActiveFrom | CountryId |
|------------+------------------+--------------+-------------|
| 1 | Iron Maiden | 1975-12-25 | 3 |
| 2 | AC/DC | 1973-01-11 | 2 |
| 3 | Allan Holdsworth | 1969-01-01 | 3 |
| 4 | Buddy Rich | 1919-01-01 | 6 |
| 5 | Devin Townsend | 1993-01-01 | 8 |
+------------+------------------+--------------+-------------+
SELECT TOP(5) * FROM Albums;
+-----------+------------------------+---------------+------------+-----------+
| AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId |
|-----------+------------------------+---------------+------------+-----------|
| 1 | Powerslave | 1984-09-03 | 1 | 1 |
| 2 | Powerage | 1978-05-05 | 2 | 1 |
| 3 | Singing Down the Lane | 1956-01-01 | 6 | 3 |
| 4 | Ziltoid the Omniscient | 2007-05-21 | 5 | 1 |
| 5 | Casualties of Cool | 2014-05-14 | 5 | 1 |
+-----------+------------------------+---------------+------------+-----------+
功能
CREATE FUNCTION [dbo].[ufn_AlbumCount] (@ArtistId int)
RETURNS smallint
AS
BEGIN
DECLARE @AlbumCount int;
SELECT @AlbumCount = COUNT(AlbumId)
FROM Albums
WHERE ArtistId = @ArtistId;
RETURN @AlbumCount;
END;
GO
现在,(在 SQL Server 上),在使用ALTER TABLE Artists ADD AlbumCount AS dbo.ufn_AlbumCount(ArtistId);
whe 更新第一个表字段后,可以列出并获得以下结果。
+------------+------------------+--------------+-------------+--------------+
| ArtistId | ArtistName | ActiveFrom | CountryId | AlbumCount |
|------------+------------------+--------------+-------------+--------------|
| 1 | Iron Maiden | 1975-12-25 | 3 | 5 |
| 2 | AC/DC | 1973-01-11 | 2 | 3 |
| 3 | Allan Holdsworth | 1969-01-01 | 3 | 2 |
| 4 | Buddy Rich | 1919-01-01 | 6 | 1 |
| 5 | Devin Townsend | 1993-01-01 | 8 | 3 |
| 6 | Jim Reeves | 1948-01-01 | 6 | 1 |
| 7 | Tom Jones | 1963-01-01 | 4 | 3 |
| 8 | Maroon 5 | 1994-01-01 | 6 | 0 |
| 9 | The Script | 2001-01-01 | 5 | 1 |
| 10 | Lit | 1988-06-26 | 6 | 0 |
+------------+------------------+--------------+-------------+--------------+
但是如何在 postgresql 上实现这一点?
解决方案
Postgres 不支持“虚拟”计算列(即在运行时生成的计算列),因此没有完全等价的。最有效的解决方案是考虑到这一点的视图:
create view artists_with_counts
as
select a.*,
coalesce(t.album_count, 0) as album_count
from artists a
left join (
select artist_id, count(*) as album_count
from albums
group by artist_id
) t on a.artist_id = t.artist_id;
另一种选择是创建一个可以在选择中用作“虚拟列”的函数 - 但由于这是逐行完成的,这将比视图慢得多。
create function album_count(p_artist artists)
returns bigint
as
$$
select count(*)
from albums a
where a.artist_id = p_artist.artist_id;
$$
language sql
stable;
然后您可以将其包含为一列:
select a.*, a.album_count
from artists a;
使用这样的函数,需要在函数引用前加上表别名(或者,您可以使用album_count(a)
)
推荐阅读
- c - 使用 Pipes 创建 N 个子节点并向父节点发送消息
- python - 在 pyspark 中的 StringIndexer/OneHotEncoder/VectorAssembler 之后使用 StandardScaler 时出错
- c# - 使用 MaxDegreeOfParallism 进行并行 foreach,有时会在两者之间停止进程
- nginx - 带有 Nginx 反向代理的 Nginx 入口控制器
- android - 实时数据:候选分辨率将很快更改
- docker - 如何在 Jenkins 声明式管道中删除 docker 代理的图像?
- linux - egrep AND 多个模式的条件不起作用
- c# - 如何同时完成对可观察集合的 HTTP 调用?
- java - 在 Gauge 中启动 Eyes Applitools 时出现 NoSuchFieldError EXCLUDE_EMPTY
- aws-lambda - 将 base64 字符串作为应用程序/pdf 处理 API 网关上的单个端点