sql - Postgresql - 列数未知的数据透视表

标签 sql postgresql pivot-table

我正在尝试在 pgsql 函数中创建并返回一个数据透视表。我遇到的问题是函数返回的列数取决于用户选择的日期范围。

我目前正在使用 colpivot 函数 ( https://github.com/hnsl/colpivot/blob/master/README.md ),这在标准查询中工作正常,但在函数中却不行,因为需要在调用时设置返回类型。

方法

第 1 步:

create  temp table _test (
dt timestamp without time zone, id integer,  NumericValue numeric
)

第 2 步:

insert into _test(dt , id ,NumericValue)
SELECT DISTINCT "T03017_PSR_LOG"."DateTime", 
    "T03017_PSR_LOG"."ID",
    "T03017_PSR_LOG"."NumericValue"
FROM "T03017_PSR_LOG"
INNER JOIN "T03002_PSR_TAG_REG" ON "T03017_PSR_LOG"."TagID" = "T03002_PSR_TAG_REG"."TagID"
WHERE "T03017_PSR_LOG"."DateTime" > 2018-10-02 AND "T03017_PSR_LOG"."DateTime" < 2018-10-07,    
ORDER BY "DateTime", "ID";

第 3 步:

select colpivot('_test_pivoted', 'select * from _test', array['tagid'], array['dt'], '#.numericvalue', null);

select * from _test_pivoted order by tagid;

如果我将上面的代码作为标准查询运行,它将返回如下内容:

ID   2018-10-03   2018-10-04   2018-10-05   2018-10-06

10   1405717.00   1453189.00   1499992.00   1546791.00
11   359102.00    371282.00    383042.00    395047.00

我需要类似上表的东西从函数返回,其中日期时间范围将是传递给函数的 2 个变量,但是我似乎无法找到解决方案,因为我不确定如何设置返回由于返回列的动态特性,请在函数顶部键入。

最佳答案

这可能看起来有点笨拙,但我不知道有什么方法可以返回可变数量的列,我认为最好的选择是使用数组。

在不了解您的数据的情况下,我只能假设您有数据缺口,这意味着并非每个 ID 都有每个日期的数据点,所以我要做的第一个任务是填补缺口并确定每个可能的日期组合和ID。

with all_dates as (
  select distinct dt from _test
),
all_ids as (
  select distinct id from _test
)
select id, dt
from all_dates
cross join all_ids

从那里,我将把它连接回原始数据集,这样每一行数组中的每个元素都指向同一事物(即,如果一行中的元素 #5 是 2017 年 11 月,那么这意味着对于每一行).

这是整个查询的样子:

with all_dates as (
  select distinct dt from _test
),
all_ids as (
  select distinct id from _test
),
all_combo as (
  select id, dt
  from all_dates
  cross join all_ids
),
pivot_data as (
  select
    a.dt, a.id, coalesce (t.NumericValue, 0) as NumericValue
  from
    all_combo a
    left join _test t on
      a.id = t.id and
      a.dt = t.dt
  order by
    a.id, a.dt
)
select
  id, array_agg(NumericValue) as valuez
from pivot_data
group by id

这会有点重复(每一行都有相同的值),但您也可以将日期范围作为数组包含在内:

select
  id, array_agg(dt) as dates, array_agg(NumericValue) as valuez

关于sql - Postgresql - 列数未知的数据透视表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52853112/

相关文章:

sql - 将周日期部分编号转换为周内的日期(...的一周)

sql - Postgres 9.4 : fast way to convert color from hex to rgb representation

postgresql - 如何使用 dbeaver 连接到在本地主机上运行的 docker 上设置的 Postgresql?

java - PostgreSQL getSequence 当前值并传递给 id

google-sheets - 使用 QUERY 公式重现数据透视表

excel - 日期范围内数据的总和数组,其中日期是文本

java - 在 Java 中声明 SQL 变量

mysql - 有什么方法可以在同一个查询中获得第 95 个百分位数和总和?

SQL 通过多个列从表中选择不同的行,忽略列顺序(意义)

excel - 在 ActiveX 按钮单击上捕获工作表名称