Postgresql - 检索查询中的引用字段

时间:2016-08-11 08:30:15

标签: postgresql

我有一个像

这样的表格
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仍然可以改变任何事情......

2 个答案:

答案 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是主键),但这并不意味着您需要一个函数。查询只是行为就像一个函数。