我有实验,功能和feature_values。特征在不同的实验中具有价值。所以我有类似的东西:
Experiments:
experiment_id, experiment_name
Features:
feature_id, feature_name
Feature_values:
experiment_id, feature_id, value
让我们说,我有三个实验(exp1,exp2,exp3)和三个特征(feat1,feat2,feat3)。 我想有一个看起来像这样的SQL结果:
feature_name | exp1 | exp2 | exp3
-------------+------+------+-----
feat1 | 100 | 150 | 110
feat2 | 200 | 250 | 210
feat3 | 300 | 350 | 310
我该怎么做? 此外,一个特征可能在一个实验中没有值。
feature_name | exp1 | exp2 | exp3
-------------+------+------+-----
feat1 | 100 | 150 | 110
feat2 | 200 | | 210
feat3 | | 350 | 310
SQL-Query应具有良好的性能。将来,feature_values表中可能有数千万个条目。 或者有更好的方法来处理数据吗?
答案 0 :(得分:4)
这是一个常见的请求。它被称为枢轴或交叉表查询。 PostgreSQL没有任何漂亮的内置语法,但您可以使用the crosstab
function from the tablefunc
module to do what you want。
有关详情,请搜索[postgresql] [pivot]
或[postgresql] [crosstab]
。
一些关系数据库系统提供了一种使用内置查询执行此操作的好方法,但到目前为止PostgreSQL却没有。
答案 1 :(得分:3)
我在此假设feature_id, experiment_id
是Feature_values
的唯一键。
执行此操作的标准SQL方法是进行n连接
select
F.feature_name,
FV1.value as exp1,
FV2.value as exp2,
FV3.value as exp3
from Features as F
left outer join Feature_values as FV1 on FV1.feature_id = F.feature_id and FV1.experiment_id = 1
left outer join Feature_values as FV2 on FV2.feature_id = F.feature_id and FV2.experiment_id = 2
left outer join Feature_values as FV3 on FV3.feature_id = F.feature_id and FV3.experiment_id = 3
或像这样的数据透视数据(聚合max
实际上并没有聚合任何东西):
select
F.feature_name,
max(case when E.experiment_name = 'exp1' then FV.value end) as exp1,
max(case when E.experiment_name = 'exp2' then FV.value end) as exp2,
max(case when E.experiment_name = 'exp3' then FV.value end) as exp3
from Features as F
left outer join Feature_values as FV on FV.feature_id = F.feature_id
left outer join Experiments as E on E.experiment_id = FV.experiment_id
group by F.feature_name
order by F.feature_name
答案 2 :(得分:2)
你尝试的是有点困难,因为你试图将一组表作为单个表提供,显然,这涉及一些转换和一些假设。
假设您事先知道只有3个实验且只有3个功能,您可以执行以下操作
SELECT
feature_id,
SUM(CASE WHEN experiment_id = 1 THEN value ELSE 0 END) AS Exp1Total,
SUM(CASE WHEN experiment_id = 2 THEN value ELSE 0 END) AS Exp2Total,
SUM(CASE WHEN experiment_id = 3 THEN value ELSE 0 END) AS Exp3Total,
FROM
Feature_values
GROUP BY
feature_id
ORDER BY
feature_id
在这种情况下,您的表格将包含实验ID和功能,而不是其名称。要获取他们的名字,您需要加入Features表以及Experiments表。为清楚起见,我省略了这一点,因为我认为最困难的部分是案例逻辑。