我的复合类型看起来像
CREATE TYPE member AS (
id BIGINT,
type CHAR(1)
);
我有一个表依赖于带有数组的member
类型。
CREATE TABLE relation (
id BIGINT PRIMARY KEY,
members member[]
);
我有三个其他表,每个表都有不同的架构(但有共同的id
字段)
CREATE TABLE table_x (
id BIGINT PRIMARY KEY,
some_text TEXT
);
CREATE TABLE table_y (
id BIGINT PRIMARY KEY,
some_int INT
);
CREATE TABLE table_z (
id BIGINT PRIMARY KEY,
some_date TIMESTAMP
);
type
类型中的 member
字段只是一个字符,用于查找特定成员所属的表。 relation
表格中的一行可以混合使用不同的type
。
我有一个场景需要返回relation
个ID,其中至少有一个member
根据其类型满足某个条件(让我们说x
=> some_text
不为空或y
=> some_int
大于10或z
=> some_date
是从现在开始的一周)
我可以通过向数据库发出多个请求来在应用程序端实现此方案:
relation
表member
relation
个数据
relation
s 我想知道是否有办法将列值映射到表名并加入它们。
答案 0 :(得分:0)
假设
relation.members
数组没有多个相同类型的成员元素。正确的吗?查询尝试
with unnested_members as (
-- Unnest members array
select id, unnest(members) members
from relation
)
, members_joined as (
-- left join on a per type basis with table_x, table_y and table_z.
select r.id, (r.members).id idext, (r.members).type,
x.some_text, y.some_int, z.some_date -- more types, more columns here
from unnested_members r
left join table_x x on (x.id = (r.members).id and (r.members).type = 'x')
left join table_y y on (y.id = (r.members).id and (r.members).type = 'y')
left join table_z z on (z.id = (r.members).id and (r.members).type = 'z')
-- More types, more tables to left join
)
select id,
max(some_text) some_text, -- use max() to get not null value for this id
max(some_int) some_int, -- use max() to get not null value for this id
max(some_date) some_date -- use max() to get not null value for this id
-- more types, more max() columns here
from members_joined
group by id -- get one row per relation.id with data from joined table_* columns
如果您需要包含更多表格,则必须在left join
部分中包含这些表格,同时在select
列表和max()
部分中添加该列。
答案 1 :(得分:0)
relation
表的大小也相当小。
我通过简单地获取每种类型的行并合并它们来解决问题:
SELECT relation.* FROM relation, UNNEST(relation.members) member INNER JOIN table_x ON member.id = table_x.id WHERE member.type = 'x' AND table_x.some_text = 'some text value'
UNION
SELECT relation.* FROM relation, UNNEST(relation.members) member INNER JOIN table_y ON member.id = table_y.id WHERE member.type = 'y' AND table_y.some_int = 123
UNION
SELECT relation.* FROM relation, UNNEST(relation.members) member INNER JOIN table_z ON member.id = table_z.id WHERE member.type = 'z' AND table_z.some_date > '2017-01-11 00:00:00';