我有一个像
这样的表格CREATE TABLE data
(value1 smallint references labels,
value2 smallint references labels,
value3 smallint references labels,
otherdata varchar(32)
);
和第二个“标签保存”表创建类似
CREATE TABLE labels (id serial primary key, name varchar(32));
它背后的基本原理是value1-3是一组非常有限的字符串(6个选项),并且将它们作为varchar类型直接输入数据表似乎效率低下。另一方面,这些偶尔会改变,这使得枚举类型不合适。
我的问题是,如何执行单个查询,而不是标签ID,而是获得相关标签? 我看着为它创建一个函数,偶然发现我需要将标签保存表名称传递给函数(模式中有几个这样的(标签保持)表)。我是否需要为每个标签表创建一个函数以避免这种情况?
create or replace function translate
(ref_id smallint,reference_table regclass) returns varchar(128) as
$$
begin
select name from reference_table where id = ref_id;
return name;
end;
$$
language plpgsql;
然后再做
select
translate(value1, labels) as foo,
translate(value2, labels) as bar
from data;
然而
错误ERROR: relation "reference_table" does not exist
所有建议都欢迎 - 此时a仍然可以改变任何事情......
答案 0 :(得分:0)
您可以将标签表名称作为字符串传递,将查询构造为字符串并execute
:
sql = `select name from ` || reference_table_name || `where id = ` || ref_id;
EXECUTE sql INTO name;
RETURN name;
答案 1 :(得分:0)
CREATE TABLE labels
( id smallserial primary key
, name varchar(32) UNIQUE -- <<-- might want this, too
);
CREATE TABLE data
( value1 smallint NOT NULL REFERENCES labels(id) -- <<-- here
, value2 smallint NOT NULL REFERENCES labels(id)
, value3 smallint NOT NULL REFERENCES labels(id)
, otherdata varchar(32)
, PRIMARY KEY (value1,value2,value3) -- <<-- added primary key here
);
-- No need for a function here.
-- For small sizes of the `labels` table, the query below will always
-- result in hash-joins to perform the lookups.
SELECT l1.name AS name1, l2.name AS name2, l3.name AS name3
, d.otherdata AS the_data
FROM data d
JOIN labels l1 ON l1.id = d.value1
JOIN labels l2 ON l2.id = d.value2
JOIN labels l3 ON l3.id = d.value3
;
注意:labels.id -> labels.name
是函数依赖项(id是主键),但这并不意味着您需要一个函数。查询只是行为就像一个函数。