【发布时间】:2016-04-04 18:51:38
【问题描述】:
我正在尝试将一些格式不正确的数据迁移到数据库中。数据来自 CSV,并首先加载到所有 varchar 列的临时表中(因为在这个阶段我无法强制类型安全)。
数据可能看起来像
COL1 | COL2 | COL3
Name 1 | |
2/11/16 | $350 | $230
2/12/16 | $420 | $387
2/13/16 | $435 | $727
Name 2 | |
2/11/16 | $121 | $144
2/12/16 | $243 | $658
2/13/16 | $453 | $214
第一列混合了公司名称作为伪标题,以及与第 2 列和第 3 列数据相关的日期。我想通过创建一个“品牌”列开始转换数据 - 如果 Col2 为 NULL,则“StoreBrand”是 Col1 的值,否则是前一行的 StoreBrand。像这样的:
COL1 | COL2 | COL3 | StoreBrand
Name 1 | | | Name 1
2/11/16 | $350 | $230 | Name 1
2/12/16 | $420 | $387 | Name 1
2/13/16 | $435 | $727 | Name 1
Name 2 | | | Name 2
2/11/16 | $121 | $144 | Name 2
2/12/16 | $243 | $658 | Name 2
2/13/16 | $453 | $214 | Name 2
这是我写的:
SELECT
t.*,
CASE
WHEN t.COL2 IS NULL THEN COL1
ELSE LAG(StoreBrand) OVER ()
END AS StoreBrand
FROM
(
SELECT
ROW_NUMBER() OVER () AS i,
*
FROM
Staging_Data
) t;
但是数据库(在这种情况下为 postgres,但我们正在考虑替代方案,因此首选最多样化的答案)在 LAG(StoreBrand) 上阻塞,因为这是我正在创建的派生列。调用 LAG(Col1) 只会填充第一行的真实数据:
COL1 | COL2 | COL3 | StoreBrand
Name 1 | | | Name 1
2/11/16 | $350 | $230 | Name 1
2/12/16 | $420 | $387 | 2/11/16
2/13/16 | $435 | $727 | 2/12/16
Name 2 | | | Name 2
2/11/16 | $121 | $144 | Name 2
2/12/16 | $243 | $658 | 2/11/16
2/13/16 | $453 | $214 | 2/12/16
我的目标是 StoreBrand 列,它是下一个品牌名称之前所有日期值的 COL1 的第一个值:
COL1 | COL2 | COL3 | StoreBrand
Name 1 | | | Name 1
2/11/16 | $350 | $230 | Name 1
2/12/16 | $420 | $387 | Name 1
2/13/16 | $435 | $727 | Name 1
Name 2 | | | Name 2
2/11/16 | $121 | $144 | Name 2
2/12/16 | $243 | $658 | Name 2
2/13/16 | $453 | $214 | Name 2
当 Col2 和 Col3 为 null 时,StoreBrand 的值无关紧要 - 该行将作为转换过程的一部分被删除。重要的是将数据行(即带有日期的行)与其品牌相关联。
有没有办法引用我缺少的列的先前值?
【问题讨论】:
-
结果应该是什么样子?
-
您是否使用某种行号列(例如,
serial)导入了保留原始顺序的数据。 -
Gordon,数据库正在维护订单,如果有帮助,可以使用类似 row_number() 的方法获取特定值
-
使用plpgsql代替纯sql会容易很多。当然,如果你没有反对的话。
标签: sql postgresql self-reference