我有一个 Postgresql 8.1 数据库。在一张表中,有三列:first_name、last_name、display_name。
是否可以将 的默认值设置display_name为first_name + " " + last_name?
Phi*_*lᵀᴹ 19
使用触发器。
这是一些您可以用作基础的代码。如果您还需要处理 UPDATE,则只需要进行很小的更改。
create table people
(
first_name varchar(20),
last_name varchar(20),
display_name varchar(40)
);
CREATE TABLE
CREATE OR REPLACE FUNCTION people_insert() RETURNS trigger AS '
BEGIN
NEW.display_name := NEW.first_name||'' ''||NEW.last_name;
RETURN NEW;
END;
' LANGUAGE plpgsql;
postgres=# CREATE FUNCTION
CREATE TRIGGER people_insert BEFORE INSERT OR UPDATE ON people FOR
EACH ROW EXECUTE PROCEDURE people_insert();
postgres=# CREATE TRIGGER
insert into people values ('Larry','Ellison');
postgres=# INSERT 0 1
postgres=# select * from people;
first_name | last_name | display_name
------------+-----------+---------------
Larry | Ellison | Larry Ellison
(1 row)
postgres=#
Run Code Online (Sandbox Code Playgroud)
kgr*_*ttn 18
您不需要实际存储该值;您可以创建一个可以像生成的列一样被引用的函数。一个警告是,必须始终使用表名或别名来限定引用。
CREATE TABLE person
(
id int PRIMARY KEY,
first_name text,
last_name text NOT NULL
);
INSERT INTO person
VALUES
(1, 'John', 'Smith'),
(2, 'Jane', 'Doe'),
(3, NULL, 'Prince');
CREATE FUNCTION display_name(rec person)
RETURNS text
STABLE
LANGUAGE SQL
COST 5
AS $$
SELECT
CASE
WHEN $1.first_name IS NULL THEN ''
ELSE $1.first_name || ' '
END || $1.last_name;
$$;
SELECT p.id, p.display_name FROM person p;
Run Code Online (Sandbox Code Playgroud)
结果:
身份证 | 显示名称 ----+-------------- 1 | 约翰·史密斯 2 | 简·多伊 3 | 王子 (3 行)
您甚至可以对生成的值进行索引,包括使用基于三元组相似性的 KNN 搜索。例如:
CREATE EXTENSION pg_trgm;
CREATE INDEX person_trgm_name
ON person
USING gist
(display_name(person) gist_trgm_ops);
SELECT
p.id,
p.display_name,
similarity(p.display_name, 'Jane')
FROM person p
ORDER BY p.display_name <-> 'Jane'
LIMIT 2;
Run Code Online (Sandbox Code Playgroud)
这种类型的搜索按照与搜索字符串的“距离”的顺序从索引扫描中返回行。如果您想查看它们有多“接近”,您可以使用距离运算符 ( <->) 或similarity()函数(即 1 - 距离)。KNN 搜索可以非常快速地返回 K 个“最近邻”,即使数据集非常大。
| 归档时间: |
|
| 查看次数: |
32091 次 |
| 最近记录: |