我正在使用PostgreSQL数据库,并有一个表格如下:
--------------------------------------
| Date | MetricType | MetricValue |
--------------------------------------
| date1 | MetricA | val |
--------------------------------------
| date1 | MetricB | val |
--------------------------------------
| date1 | MetricC | val |
--------------------------------------
| date2 | MetricA | val |
--------------------------------------
| date2 | MetricB | val |
--------------------------------------
| date2 | MetricC | val |
--------------------------------------
如您所见,每个日期都有一组度量标准类型,每种类型都有一个值。我想编写一个Select语句,它将这些数据组合在以下庄园中
------------------------------------------
| Date | MetricA | MetricB | MetricC |
------------------------------------------
| date1 | val | val | val |
------------------------------------------
| date2 | val | val | val |
------------------------------------------
我不确定如何编写此Select语句以获得这些结果。有人可以帮忙吗?
答案 0 :(得分:2)
请参阅http://www.artfulsoftware.com/infotree/queries.php#78
对于教程,您要查找的内容称为“数据透视”。这也可以使用CASE完成,如下所示:http://stackoverflow.com/questions/1241178/mysql-rows-to-columns
答案 1 :(得分:2)
此数据转换是 pivot 。如果您的数据库没有pivot函数,那么您可以使用带有CASE
表达式的聚合函数:
select Date,
max(case when MetricType = 'MetricA' then MetricValue end) MetricA,
max(case when MetricType = 'MetricB' then MetricValue end) MetricB,
max(case when MetricType = 'MetricC' then MetricValue end) MetricC
from yourtable
group by Date
结果是:
| DATE | METRICA | METRICB | METRICC |
---------------------------------------
| date1 | val | val | val |
| date2 | val | val | val |
您也可以使用表格上的多个联接来执行此操作:
select a.date as Date,
a.MetricValue as MetricA,
b.MetricValue as MetricB,
c.MetricValue as MetricC
from yourtable a
left join yourtable b
on a.date = b.date and b.MetricType = 'MetricB'
left join yourtable c
on a.date = c.date and c.MetricType = 'MetricC'
where a.MetricType = 'MetricA'
答案 2 :(得分:2)
实际上,Postgres 确实具有透视功能。安装附加模块tablefunc
在此相关问题下查找更多详细信息和解释:
PostgreSQL Crosstab Query
您的查询可能如下所示。假设指标属于数据类型integer
:
SELECT * FROM crosstab(
'SELECT date, metrictype, metricvalue
FROM tbl
ORDER BY 1,2' -- could also just be "ORDER BY 1" here
,$$VALUES ('MetricA'::text), ('MetricB'), ('MetricC')$$)
AS ct ("Section" text, "MetricA" int, "MetricB" int, "MetricC" int);
对于简单查询,CASE
语句like demonstrated by @Bluefeet即可。但是这个查询可以更快地执行更多,并且对于更长的列/更大的表列表来说更短。
答案 3 :(得分:0)
select a.date as Date,
a.metric as MetricType ,
b.metric as MetricType ,
c.metric as MetricType
from (select distinct date from yourtable where metric = 'metricA') a
join yourtable b on a.date = b.date and b.metric = 'metricB'
join yourtable c on a.date = c.date and c.metric = 'metricC'