PostgreSQL交叉表函数
我对交叉表函数有一些问题 我的桌子“t”是空的 我想要这个“透视表”t\u透视图 Sql代码是PostgreSQL交叉表函数,sql,postgresql,pivot,crosstab,Sql,Postgresql,Pivot,Crosstab,我对交叉表函数有一些问题 我的桌子“t”是空的 我想要这个“透视表”t\u透视图 Sql代码是 SELECT * from crosstab ( 'SELECT day,name,hour,cause, SUM(c_p) AS c_p FROM t GROUP BY 1,2,3,4 ORDER BY 3 ', 'SELECT DISTINCT cause FROM i ORDER BY
SELECT * from crosstab (
'SELECT day,name,hour,cause, SUM(c_p) AS c_p
FROM t
GROUP BY 1,2,3,4
ORDER BY 3 ',
'SELECT DISTINCT cause
FROM i
ORDER BY 1')
AS t_pivot (day date, name integer,hour integer, cause_0 integer,cause_1 integer)
查询结果是一行表,取决于“订单依据”
错误在哪里?
谢谢
f、 我没有使用过
交叉表
函数,现在无法测试它(sqlfiddle上没有tablefunc扩展),但一般来说,如果我需要这样的数据透视,我更喜欢简单的SQL:
select
date,
hour,
sum(case when cause = 0 then c_p else 0 end) cause_0,
sum(case when cause = 1 then c_p else 0 end) cause_1
from t
group by date, hour
order by hour
我认为以后维护和阅读它会更容易(但这是主观的观点)
更新这一行有效(小时用作行名称
,日期和名称为额外的
列):
发件人:
source_sql是生成数据源集的sql语句。
此语句必须返回一行\名称列、一个类别列、,
和一个值列。它还可能有一个或多个“额外”列。
“行名称”列必须位于第一位。类别和值列必须
请按该顺序显示最后两列。行和名称之间的任何列
和类别被视为“额外”。需要“额外”列
对于具有相同行名称值的所有行都相同
也
在实践中,源sql查询应始终指定ORDER BY 1到
确保将具有相同行名称的值放在一起。
然而,组内类别的排序并不重要。
此外,必须确保类别的顺序
查询的输出与指定的输出列顺序匹配
似乎
crosstab
函数只希望有一列保存行标识,如果我没有弄错的话,您有三列:day、name和hour。但是,交叉表
也允许额外的列,它不会将其视为特殊的,它只是将其添加到结果中
因此,对于您的案例,您必须获得这三列,并将它们表示为一列。我不确定这是否是最好的方法,但我使用了行
构造函数来实现这一点(因此我们不需要关心数据类型):
这将产生如下结果:
row_name | day | hour | name | cause_0 | cause_1
---------------------+------------+------+------+---------+---------
(2013-06-12,14,167) | 2013-06-12 | 14 | 167 | 2 | --
(2013-06-12,16,167) | 2013-06-12 | 16 | 167 | 7 | --
(2013-06-12,19,167) | 2013-06-12 | 19 | 167 | 4 | 1
(2013-06-13,14,167) | 2013-06-13 | 14 | 167 | 10 | --
(4 rows)
您不必担心第一列,它实际上对您毫无用处,因此我们可以将其删除:
SELECT day,hour,name,cause_0,cause_1 FROM (SELECT * from crosstab (
'select row(day,hour,name),day, hour, name, cause, sum(c_p) as c_p
from t
group by 2, 3, 4, 5
order by 1',
'VALUES(0),(1)')
AS t_pivot (row_name text, day date, hour int, name integer, cause_0 integer,cause_1 integer)) AS t;
还有一件事。请注意,我在第二个参数中使用了
值
,而不是选择不同的值
,如果您确定这些值是唯一可用的值(如果它不是静态的),则这是一种更好的方法,然后作为t\u轴…
也应该是动态的。是的,但我必须使用交叉表,因为这是一个更复杂的示例table@user2418290见更新,仍需阅读文档以了解其为何如此运行我认为这与OP的预期不太相符,因为若你们在不同的日子里插入相同的小时,它将产生一个不一致的结果。+1从手机上读到你们的评论,并考虑使用行作为第一列,但你们已经这样做了。我仍然更喜欢使用group by的手动轴:)
select
date,
hour,
sum(case when cause = 0 then c_p else 0 end) cause_0,
sum(case when cause = 1 then c_p else 0 end) cause_1
from t
group by date, hour
order by hour
SELECT * from crosstab (
'select hour, date, name, cause, sum(c_p) as c_p
from t
group by 1, 2, 3, 4
order by 1',
'select distinct cause from t order by 1')
AS t_pivot (hour integer, date timestamp, name integer, cause_0 integer,cause_1 integer)
SELECT * from crosstab (
'select row(day,hour,name),day, hour, name, cause, sum(c_p) as c_p
from t
group by 2, 3, 4, 5
order by 1',
'VALUES(0),(1)')
AS t_pivot (row_name text, day date, hour int, name integer, cause_0 integer,cause_1 integer);
row_name | day | hour | name | cause_0 | cause_1
---------------------+------------+------+------+---------+---------
(2013-06-12,14,167) | 2013-06-12 | 14 | 167 | 2 | --
(2013-06-12,16,167) | 2013-06-12 | 16 | 167 | 7 | --
(2013-06-12,19,167) | 2013-06-12 | 19 | 167 | 4 | 1
(2013-06-13,14,167) | 2013-06-13 | 14 | 167 | 10 | --
(4 rows)
SELECT day,hour,name,cause_0,cause_1 FROM (SELECT * from crosstab (
'select row(day,hour,name),day, hour, name, cause, sum(c_p) as c_p
from t
group by 2, 3, 4, 5
order by 1',
'VALUES(0),(1)')
AS t_pivot (row_name text, day date, hour int, name integer, cause_0 integer,cause_1 integer)) AS t;