是否可以从另一个表中的行命名SQL结果列?(博士后)
基本上,我有一个动态属性表的用户。简化:是否可以从另一个表中的行命名SQL结果列?(博士后),sql,postgresql,database-design,entity-attribute-value,Sql,Postgresql,Database Design,Entity Attribute Value,基本上,我有一个动态属性表的用户。简化: SELECT * FROM users; id | email -----+------------------------------------------ 1 | example@example.com SELECT * FROM user_attributes; id | name ----+---------------- 1 | S
SELECT * FROM users;
id | email
-----+------------------------------------------
1 | example@example.com
SELECT * FROM user_attributes;
id | name
----+----------------
1 | Salutation
2 | Given Name
3 | Surname
4 | Alias
5 | Address
6 | Address 2
7 | Address 3
8 | City
9 | Region
....
SELECT * FROM user_attribute_values;
client_id | attribute_id | value
-----------+--------------+-------
我要做的是选择,它将返回user_id、city、region列,其中city和region不为空
创建user_attributes表的原因是,可能需要存储有关用户的任意数量的自定义字段,并且不可能事先知道将它们创建为user表的列
select client_id,
min(case when attribute_id = 8 then value else '0' end) as city,
min(case when attribute_id = 9 then value else '0' end) as region
from user_attribute_values
group by clientid
having min(case when attribute_id = 8 then value else '0' end) <> '0'
or min(case when attribute_id = 9 then value else '0' end) <> '0'
这将显示具有城市或地区值的客户。如果只希望客户端同时具有这两个属性,请在having子句中将OR更改为AND。使用内部联接:
SELECT u.id, a_city.value AS city, a_region.value AS region
FROM users u
INNER JOIN user_attribute_values a_city ON a_city.client_id = u.id AND a_city.attribute_id = 8
INNER JOIN user_attribute_values a_region ON a_region.client_id = u.id AND a_region.attribute_id = 9
WHERE LENGTH(a_city.value) > 0
AND LENGTH(a_region.value) > 0
这是基于对博士后和大学内部运作的主要误解
如果没有数百个不同的字段或一组动态属性类型,请使用一个包含所有列的表-除了。没有值的列用NULL填充。
空存储非常便宜,空位图在表中每列占用1位,通常以8字节为单位分配,以覆盖64列。见:
单个附加属性的单独行至少占用额外的36字节
与更多建议密切相关的答案:
正如我可能没有充分解释的那样,我无法事先知道这些专栏将是什么。用户_属性是动态的,并且完全不可能预先确定特定用户可能想要什么。他们想追踪头发的颜色吗?用户驾驶的汽车类型?他最喜欢的零食?否则我会同意,并且会以不同的方式设计它。我不确定这在Postgresql中会如何工作,但请尝试查看动态透视表。见这个问题: 4 bytes item identifier 23 bytes heap tuple header 1 byte padding 8 bytes minimum row data size
CREATE TABLE users (
users_id serial PRIMARY KEY
, salutation text
, given_name text
, surname text
, alias text
... (many) more columns
);
CREATE TABLE address (
address_id serial PRIMARY KEY
, users_id int REFERENCES users
, city text -- or separate TABLE city incl region_id etc. ...
, region_id int REFERENCES region
, address text
... (many) more columns
);