将多行加入单行中的多列 Netezza/Postgres

Posted

技术标签:

【中文标题】将多行加入单行中的多列 Netezza/Postgres【英文标题】:JOIN multiple rows to multiple columns in single row Netezza/Postgres 【发布时间】:2016-04-28 17:05:18 【问题描述】:

我有一张像这样的表 A

Date         Name      Value
----------------------------
2015-01-01   A         12
2015-01-01   B         13
2015-01-01   C         10
2015-01-01   D          9
2015-01-01   E         15
2015-01-01   F         11
2015-01-02   A          1
2015-01-02   B          2
2015-01-02   C          3
2015-01-02   D          4
2015-01-02   E          5
2015-01-02   F          6
2015-01-03   A          7
2015-01-03   B          8
2015-01-03   C          9
2015-01-03   D         10
2015-01-03   E         15
2015-01-03   F         16
....

其中包含每天每个名称的值。我需要第二张桌子,看起来像这样

Date         Name    ValueDate    ValueDate+1     ValueDate+2
--------------------------------------------------------------
2015-01-01   A         12            1                7
2015-01-01   B         13            2                8
2015-01-01   C         10            3                9
2015-01-01   D          9            4               10
2015-01-01   E         15            5               15
2015-01-01   F         11            6               16
2015-01-02   A          1            7              ...
2015-01-02   B          2            8              ...
2015-01-02   C          3            9              ...
2015-01-02   D          4           10              ...
2015-01-02   E          5           15              ...
2015-01-02   F          6           16              ...

我尝试创建一个正确输入所有日期的中间表

Date         Name    ValueDate      ValueDate+1     ValueDate+2
----------------------------------------------------------------
2015-01-01   A         2015-01-01    2015-01-02      2015-01-03
2015-01-01   B         2015-01-01    2015-01-02      2015-01-03
2015-01-01   C         2015-01-01    2015-01-02      2015-01-03
2015-01-01   D         2015-01-01    2015-01-02      2015-01-03
2015-01-01   E         2015-01-01    2015-01-02      2015-01-03
2015-01-01   F         2015-01-01    2015-01-02      2015-01-03
...

然后我的想法是在表 a 上使用某种 JOIN 将对应的值映射到日期并使用 s.th like

CASE WHEN Date = ValueDate THEN Value ELSE NULL END AS ValueDate+1

我正在努力弄清楚如何在 SQL 中完成此操作。对于初始日期序列,我基本上需要窗口上的所有值。为了提供一些背景信息,我想在固定的时间间隔内查看该值在接下来的 x 天内的表现。数据类型是所有日期列的日期,名称的 Varchar 和值的数字。 ValueDate+1 和 +2 表示 +1/2 天。也不能排除名字的数量会随着时间的推移保持不变。

谢谢

【问题讨论】:

对我来说这是两个左连接和一个枢轴。假设您的 version of netezza 支持 pivoting... 您可能必须使用动态 sql 将日期名称生成为列标题,尤其是在列数可变的情况下。 【参考方案1】:

你只想要lead():

select a.*,
       lead(value) over (partition by name order by date) as value_1,
       lead(value, 2) over (partition by name order by date) as value_2
from a;

【讨论】:

感谢您的回复,不幸的是,如果名称计数随着时间的推移而变化,这将不起作用,我不能排除这一点 @Markus.london 。 . .我不明白你的评论。这应该从表的“下一个”行中获取每个名称的值,其中“下一个”是按日期顺序排列的下一个。这似乎是你所要求的。 我可能会遇到一些情况,例如名称 A 几天不见了,那也可以吗? @Markus.london 。 . .它给出了表中下一个日期的值。【参考方案2】:

我不清楚你的问题陈述 --

首先,您不要说数据中的“日期”是日期类型,还是只是看起来像日期的字符串。

“值”是每行数据的主键吗?或者它是用于计算“ValueDate+1”的实际值?如果是这样,怎么做?

“ValueDate”只是“Date”的值,而“ValueDate+1”是“Date”之后的第二天吗?还是下个月?

ValueDate 是否应该是“日期”加上“价值”天的值?

您能否重述问题,并包括您的数据类型?

您能否用方程式或公式以及您需要显示的输出值类型来说明问题?

如果可以,我可以向您展示如何在 SQL 中对其进行格式化。

-- 艾达

【讨论】:

我已经添加了数据类型,ValueDate+1 很简单,就是 date+1 天的值。没有公式是关于重新排列现有值的方式,您可以看到每个“名称”在接下来的几天中如何变化。值都来自表a【参考方案3】:

我找到了一种获得所需结果的方法,方法是将 row_number() 子选择限制写入所需的窗口大小。每个日期的每个条目都像这样

Date         Name      Value    Row_Num
---------------------------------------
2015-01-01    A         12        0
2015-01-01    A         12        1
2015-01-01    A         12        2
2015-01-01    A         12        3

下一步可以使用

(Date + Row_Num*INTERVAL'1 DAY')::DATE 

然后可以在初始表上连接并进行旋转。这将允许每个日期的名称任意组合。

【讨论】:

以上是关于将多行加入单行中的多列 Netezza/Postgres的主要内容,如果未能解决你的问题,请参考以下文章

多行变成单行多列

在多列的单行中显示多行数据

oracle单行多列,拆分成多行

将多行加入单行而不进行聚合 [Oracle]

将单行转换为多行

ServiceNow如何在Fufiller页面端实现String的多行与单行转换