填补与具有填充数量限制的先前记录值的差距:无法使用分析
Fill in gap with prior record value having a populated quantity LIMIT: no analytics can be used
假设数据结构如下:Demo
WITH CAL AS(
SELECT 2022 YR, '01' PERIOD UNION ALL
SELECT 2022 YR, '02' PERIOD UNION ALL
SELECT 2022 YR, '03' PERIOD UNION ALL
SELECT 2022 YR, '04' PERIOD UNION ALL
SELECT 2022 YR, '05' PERIOD UNION ALL
SELECT 2022 YR, '06' PERIOD UNION ALL
SELECT 2022 YR, '07' PERIOD UNION ALL
SELECT 2022 YR, '08' PERIOD UNION ALL
SELECT 2022 YR, '09' PERIOD UNION ALL
SELECT 2022 YR, '10' PERIOD UNION ALL
SELECT 2022 YR, '11' PERIOD UNION ALL
SELECT 2022 YR, '12' PERIOD ),
Data AS (
SELECT 2022 YR, '01' PERIOD, 10 qty UNION ALL
SELECT 2022 YR, '02' PERIOD, 5 qty UNION ALL
SELECT 2022 YR, '04' PERIOD, 10 qty UNION ALL
SELECT 2022 YR, '05' PERIOD, 7 qty UNION ALL
SELECT 2022 YR, '09' PERIOD, 1 qty)
SELECT *
FROM CAL A
LEFT JOIN data B
on A.YR = B.YR
and A.Period = B.Period
WHERE A.Period <10 and A.YR = 2022
ORDER by A.period
给我们:
+------+--------+------+--------+-----+
| YR | PERIOD | YR | PERIOD | qty |
+------+--------+------+--------+-----+
| 2022 | 01 | 2022 | 01 | 10 |
| 2022 | 02 | 2022 | 02 | 5 |
| 2022 | 03 | | | |
| 2022 | 04 | 2022 | 04 | 10 |
| 2022 | 05 | 2022 | 05 | 7 |
| 2022 | 06 | | | |
| 2022 | 07 | | | |
| 2022 | 08 | | | |
| 2022 | 09 | 2022 | 09 | 1 |
+------+--------+------+--------+-----+
预期结果为:
+------+--------+------+--------+-----+
| YR | PERIOD | YR | PERIOD | qty |
+------+--------+------+--------+-----+
| 2022 | 01 | 2022 | 01 | 10 |
| 2022 | 02 | 2022 | 02 | 5 |
| 2022 | 03 | 2022 | 03 | 5 | -- SQL derives
| 2022 | 04 | 2022 | 04 | 10 |
| 2022 | 05 | 2022 | 05 | 7 |
| 2022 | 06 | 2022 | 06 | 7 | -- SQL derives
| 2022 | 07 | 2022 | 07 | 7 | -- SQL derives
| 2022 | 08 | 2022 | 08 | 7 | -- SQL derives
| 2022 | 09 | 2022 | 09 | 1 |
+------+--------+------+--------+-----+
问题:
如何用参考最近的较早 period/year 的创纪录数量来填补 03、06、07、08 期间的空白。注意示例仅限于一年,但差距可能在 2022 年第 01 期,我们需要 return 2021 年第 12 期数量(如果已填充)或继续返回直到找到数量,或者不存在此类记录。
限制:
- 我无法使用 table 值函数。 (没有横向,没有交叉应用)
- 我无法使用分析(没有 lead/lag)
- 相关的子查询是不确定的。
为什么要限制?这必须在 HANA 图形计算视图中完成。这不支持这两个概念。我目前做的还不够,不知道如何进行相关子查询,不知道是否可行。
- 我可以根据需要创建任意数量的内联视图或 material 化数据集。
统计数据:
- 此 table 有超过一百万行,并以 productlocationperiodsyears 的速度增长。因此,如果您在 6 年内拥有 100020126=140 万+,仅 20 个地点和 1000 种产品...
- 每个产品库存可能在给定位置的月底记录。 (product/location 没有 activity,因此没有记录,因此存在间隙。RDBMS 中使用的愚蠢的大型机保存存储技术...我的意思是我怎么知道系统在插入记录时没有出错那 material; 或出于某种原因省略它... )
- 没有记录的情况,我们需要补上。提供的示例被分解为没有位置的熊骨,material 因为我不认为它对解决方案不重要。
问题:
- 我需要将 SQL 转换为“HANA 图形计算视图”
- 是的,我知道我可以创建一个 SQL 脚本来执行此操作。这是不允许的。
- 是的,我知道我可以创建一个 table 函数来执行此操作。这是不允许的。
- 这必须通过支持基本 SQL 功能的图形计算视图来完成
- BASIC Join(INNER、OUTER、FULL OUTER、Cross)、过滤器、聚合、如果对所有记录都进行评估,则会对性能产生重大影响的基本排名。 (其他一些东西)但不是 window 函数,不是交叉连接,横向...
- 至于为什么它与维护和人员配备有关。人员区域是一个报告区域,它使用工具来创建在 Universe 中使用的视图。该地区希望停止使用所有脚本,以降低员工成本,因为 SQL 未来的员工职位不需要知识,尽管它有帮助!
对于熟悉此问题的人,此问题源自 ECC 实现中的 MBEWH table
这可以通过 SAP HANA 中的图形计算视图来完成。
虽然它不是很漂亮而且可能不是很有效。
据称能够维护图形计算的人是否。 views but not SQL statement 就能成功维持这个很值得怀疑。
首先,SQL中的方法,使方法变得清晰:
create column table calendar
( yr integer
, period nvarchar (2)
, primary key (yr, period))
insert into calendar
( select year (generated_period_start) as yr
, ABAP_NUMC( month(generated_period_start), 2) as period
from series_generate_date ('INTERVAL 1 MONTH', '2022-01-01', '2023-01-01'));
create column table data
( yr integer
, period nvarchar (2)
, qty integer
, primary key (yr, period));
insert into data values (2022, '01', 10);
insert into data values (2022, '02', 5);
insert into data values (2022, '04', 10);
insert into data values (2022, '05', 7);
insert into data values (2022, '09', 1);
SELECT *
FROM CALendar A
LEFT JOIN data B
on A.YR = B.YR
and A.Period = B.Period
WHERE A.Period <'10' and A.YR =2022
ORDER BY A.period;
/*
YR PERIOD YR PERIOD QTY
2,022 01 2,022 01 10
2,022 02 2,022 02 5
2,022 03 ? ? ?
2,022 04 2,022 04 10
2,022 05 2,022 05 7
2,022 06 ? ? ?
2,022 07 ? ? ?
2,022 08 ? ? ?
2,022 09 2,022 09 1
*/
NUMC()
函数从整数创建 ABAP NUMC 字符串(带前导零)。除此之外,它几乎是来自 OP 的 tables。
一般的方法是使用 CALENDAR
table 作为主要驱动 table 来确定 dates/periods 会有输出行。
这是与 DATA
table 的外部连接,在相应的列中留下带有 NULL
的“缺失”行。
接下来,DATA
table 再次加入,这次 YEAR||PERIOD
组合严格小于 CALENDAR
YEAR||PERIOD
table。这为我们提供了 all 行 DATA
.
中的先前记录
接下来,我们需要选择要查看的前几行。
这是通过 ROWNUM()
函数和对第一条记录的筛选器完成的。
由于图形计算视图不支持 ROWNUM()
这可以与 RANK()
交换 - 只要没有两个实际的 DATA
记录用于相同的 YEAR||PERIOD
组合,这就有效。
最后,在投影中,我们使用 COALESCE
在 DATA
中可用的实际信息和 - 如果是 NULL
- 上一周期信息之间切换。
/*
CAL_YR CAL_PER COALESCE(DAT_YR,PREV_YR) COALESCE(DAT_PER,PREV_PER) COALESCE(DAT_QTY,PREV_QTY)
2,022 01 2,022 01 10
2,022 02 2,022 02 5
2,022 03 2,022 02 5
2,022 04 2,022 04 10
2,022 05 2,022 05 7
2,022 06 2,022 05 7
2,022 07 2,022 05 7
2,022 08 2,022 05 7
2,022 09 2,022 09 1
*/
到目前为止,还不错。
图形计算。视图看起来像这样:
由于对每个节点进行屏幕截图很麻烦,我将包括最重要的节点:
1. CAL_DAT_PREV
因为图形计算只支持等式连接。我们必须效仿“大于”连接的观点。为此,我创建了具有相同值的 calculated/constant 列 join_const
(在本例中为整数 1
)并加入了这些列。
2。 PREVS_ARE_OLDER
这是模拟“大于”联接的第二部分:此投影只是过滤掉 cal_yr_per
大于或等于 prev_yr_per
的记录。这里必须允许相等的值,因为我们不想丢失没有更小 YEAR||PERIOD
组合的记录。或者,可以将初始记录插入 DATA
table,保证小于所有其他条目,例如YEAR
= 0001
和 PERIOD
=00
或类似的东西。如果您熟悉 SAP 应用程序 table,那么您已经见过这种方法。
顺便说一下 - 为方便起见,我创建了计算列,将 YEAR
和 PERIOD
组合用于不同的 tables - cal_yr_per
、dat_yr_per
, 和 prev_yr_per
.
3。 RANK_1
此处为 PREV_YR_PR
创建排名,仅选择第一个,并为 cal_yr_per
的每个新值开始一个新组。
该值通过 Rank_Column
.
返回
4. REDUCE_PREV
拼图的最后一块:在 Rank_Column
= 1 上使用过滤器,我们确保每个“日历”行只得到一个“前一”行。
另外:通过 IF(ISNULL(...), ... , ...)
我们在三个计算列中模拟 COALESCE(...)
,恰当地命名为 FILL...
.
这就是该解决方案的具体细节。
“它在我的电脑上运行!” 可能是我能说的最好的了。
SELECT "CAL_YR", "CAL_PERIOD"
, "DAT_YR", "DAT_PER", "DAT_QTY"
, "FILL_YR", "FILL_QTY", "FILL_PER"
FROM "_SYS_BIC"."scratch/QTY_FILLUP"
ORDER BY "CAL_YR" asc, "CAL_PERIOD" asc;
/*
CAL_YR CAL_PERIOD DAT_YR DAT_PER DAT_QTY FILL_YR FILL_QTY FILL_PER
2,022 01 2,022 01 10 2,022 10 01
2,022 02 2,022 02 5 2,022 5 02
2,022 03 ? ? ? 2,022 5 02
2,022 04 2,022 04 10 2,022 10 04
2,022 05 2,022 05 7 2,022 7 05
2,022 06 ? ? ? 2,022 7 05
2,022 07 ? ? ? 2,022 7 05
2,022 08 ? ? ? 2,022 7 05
2,022 09 2,022 09 1 2,022 1 09
2,022 10 ? ? ? 2,022 1 09
2,022 11 ? ? ? 2,022 1 09
2,022 12 ? ? ? 2,022 1 09
*/
假设数据结构如下:Demo
WITH CAL AS(
SELECT 2022 YR, '01' PERIOD UNION ALL
SELECT 2022 YR, '02' PERIOD UNION ALL
SELECT 2022 YR, '03' PERIOD UNION ALL
SELECT 2022 YR, '04' PERIOD UNION ALL
SELECT 2022 YR, '05' PERIOD UNION ALL
SELECT 2022 YR, '06' PERIOD UNION ALL
SELECT 2022 YR, '07' PERIOD UNION ALL
SELECT 2022 YR, '08' PERIOD UNION ALL
SELECT 2022 YR, '09' PERIOD UNION ALL
SELECT 2022 YR, '10' PERIOD UNION ALL
SELECT 2022 YR, '11' PERIOD UNION ALL
SELECT 2022 YR, '12' PERIOD ),
Data AS (
SELECT 2022 YR, '01' PERIOD, 10 qty UNION ALL
SELECT 2022 YR, '02' PERIOD, 5 qty UNION ALL
SELECT 2022 YR, '04' PERIOD, 10 qty UNION ALL
SELECT 2022 YR, '05' PERIOD, 7 qty UNION ALL
SELECT 2022 YR, '09' PERIOD, 1 qty)
SELECT *
FROM CAL A
LEFT JOIN data B
on A.YR = B.YR
and A.Period = B.Period
WHERE A.Period <10 and A.YR = 2022
ORDER by A.period
给我们:
+------+--------+------+--------+-----+
| YR | PERIOD | YR | PERIOD | qty |
+------+--------+------+--------+-----+
| 2022 | 01 | 2022 | 01 | 10 |
| 2022 | 02 | 2022 | 02 | 5 |
| 2022 | 03 | | | |
| 2022 | 04 | 2022 | 04 | 10 |
| 2022 | 05 | 2022 | 05 | 7 |
| 2022 | 06 | | | |
| 2022 | 07 | | | |
| 2022 | 08 | | | |
| 2022 | 09 | 2022 | 09 | 1 |
+------+--------+------+--------+-----+
预期结果为:
+------+--------+------+--------+-----+
| YR | PERIOD | YR | PERIOD | qty |
+------+--------+------+--------+-----+
| 2022 | 01 | 2022 | 01 | 10 |
| 2022 | 02 | 2022 | 02 | 5 |
| 2022 | 03 | 2022 | 03 | 5 | -- SQL derives
| 2022 | 04 | 2022 | 04 | 10 |
| 2022 | 05 | 2022 | 05 | 7 |
| 2022 | 06 | 2022 | 06 | 7 | -- SQL derives
| 2022 | 07 | 2022 | 07 | 7 | -- SQL derives
| 2022 | 08 | 2022 | 08 | 7 | -- SQL derives
| 2022 | 09 | 2022 | 09 | 1 |
+------+--------+------+--------+-----+
问题: 如何用参考最近的较早 period/year 的创纪录数量来填补 03、06、07、08 期间的空白。注意示例仅限于一年,但差距可能在 2022 年第 01 期,我们需要 return 2021 年第 12 期数量(如果已填充)或继续返回直到找到数量,或者不存在此类记录。
限制:
- 我无法使用 table 值函数。 (没有横向,没有交叉应用)
- 我无法使用分析(没有 lead/lag)
- 相关的子查询是不确定的。
为什么要限制?这必须在 HANA 图形计算视图中完成。这不支持这两个概念。我目前做的还不够,不知道如何进行相关子查询,不知道是否可行。
- 我可以根据需要创建任意数量的内联视图或 material 化数据集。
统计数据:
- 此 table 有超过一百万行,并以 productlocationperiodsyears 的速度增长。因此,如果您在 6 年内拥有 100020126=140 万+,仅 20 个地点和 1000 种产品...
- 每个产品库存可能在给定位置的月底记录。 (product/location 没有 activity,因此没有记录,因此存在间隙。RDBMS 中使用的愚蠢的大型机保存存储技术...我的意思是我怎么知道系统在插入记录时没有出错那 material; 或出于某种原因省略它... )
- 没有记录的情况,我们需要补上。提供的示例被分解为没有位置的熊骨,material 因为我不认为它对解决方案不重要。
问题:
- 我需要将 SQL 转换为“HANA 图形计算视图”
- 是的,我知道我可以创建一个 SQL 脚本来执行此操作。这是不允许的。
- 是的,我知道我可以创建一个 table 函数来执行此操作。这是不允许的。
- 这必须通过支持基本 SQL 功能的图形计算视图来完成
- BASIC Join(INNER、OUTER、FULL OUTER、Cross)、过滤器、聚合、如果对所有记录都进行评估,则会对性能产生重大影响的基本排名。 (其他一些东西)但不是 window 函数,不是交叉连接,横向...
- 至于为什么它与维护和人员配备有关。人员区域是一个报告区域,它使用工具来创建在 Universe 中使用的视图。该地区希望停止使用所有脚本,以降低员工成本,因为 SQL 未来的员工职位不需要知识,尽管它有帮助!
对于熟悉此问题的人,此问题源自 ECC 实现中的 MBEWH table
这可以通过 SAP HANA 中的图形计算视图来完成。
虽然它不是很漂亮而且可能不是很有效。 据称能够维护图形计算的人是否。 views but not SQL statement 就能成功维持这个很值得怀疑。
首先,SQL中的方法,使方法变得清晰:
create column table calendar
( yr integer
, period nvarchar (2)
, primary key (yr, period))
insert into calendar
( select year (generated_period_start) as yr
, ABAP_NUMC( month(generated_period_start), 2) as period
from series_generate_date ('INTERVAL 1 MONTH', '2022-01-01', '2023-01-01'));
create column table data
( yr integer
, period nvarchar (2)
, qty integer
, primary key (yr, period));
insert into data values (2022, '01', 10);
insert into data values (2022, '02', 5);
insert into data values (2022, '04', 10);
insert into data values (2022, '05', 7);
insert into data values (2022, '09', 1);
SELECT *
FROM CALendar A
LEFT JOIN data B
on A.YR = B.YR
and A.Period = B.Period
WHERE A.Period <'10' and A.YR =2022
ORDER BY A.period;
/*
YR PERIOD YR PERIOD QTY
2,022 01 2,022 01 10
2,022 02 2,022 02 5
2,022 03 ? ? ?
2,022 04 2,022 04 10
2,022 05 2,022 05 7
2,022 06 ? ? ?
2,022 07 ? ? ?
2,022 08 ? ? ?
2,022 09 2,022 09 1
*/
NUMC()
函数从整数创建 ABAP NUMC 字符串(带前导零)。除此之外,它几乎是来自 OP 的 tables。
一般的方法是使用 CALENDAR
table 作为主要驱动 table 来确定 dates/periods 会有输出行。
这是与 DATA
table 的外部连接,在相应的列中留下带有 NULL
的“缺失”行。
接下来,DATA
table 再次加入,这次 YEAR||PERIOD
组合严格小于 CALENDAR
YEAR||PERIOD
table。这为我们提供了 all 行 DATA
.
接下来,我们需要选择要查看的前几行。
这是通过 ROWNUM()
函数和对第一条记录的筛选器完成的。
由于图形计算视图不支持 ROWNUM()
这可以与 RANK()
交换 - 只要没有两个实际的 DATA
记录用于相同的 YEAR||PERIOD
组合,这就有效。
最后,在投影中,我们使用 COALESCE
在 DATA
中可用的实际信息和 - 如果是 NULL
- 上一周期信息之间切换。
/*
CAL_YR CAL_PER COALESCE(DAT_YR,PREV_YR) COALESCE(DAT_PER,PREV_PER) COALESCE(DAT_QTY,PREV_QTY)
2,022 01 2,022 01 10
2,022 02 2,022 02 5
2,022 03 2,022 02 5
2,022 04 2,022 04 10
2,022 05 2,022 05 7
2,022 06 2,022 05 7
2,022 07 2,022 05 7
2,022 08 2,022 05 7
2,022 09 2,022 09 1
*/
到目前为止,还不错。
图形计算。视图看起来像这样:
由于对每个节点进行屏幕截图很麻烦,我将包括最重要的节点:
1. CAL_DAT_PREV
因为图形计算只支持等式连接。我们必须效仿“大于”连接的观点。为此,我创建了具有相同值的 calculated/constant 列 join_const
(在本例中为整数 1
)并加入了这些列。
2。 PREVS_ARE_OLDER
这是模拟“大于”联接的第二部分:此投影只是过滤掉 cal_yr_per
大于或等于 prev_yr_per
的记录。这里必须允许相等的值,因为我们不想丢失没有更小 YEAR||PERIOD
组合的记录。或者,可以将初始记录插入 DATA
table,保证小于所有其他条目,例如YEAR
= 0001
和 PERIOD
=00
或类似的东西。如果您熟悉 SAP 应用程序 table,那么您已经见过这种方法。
顺便说一下 - 为方便起见,我创建了计算列,将 YEAR
和 PERIOD
组合用于不同的 tables - cal_yr_per
、dat_yr_per
, 和 prev_yr_per
.
3。 RANK_1
此处为 PREV_YR_PR
创建排名,仅选择第一个,并为 cal_yr_per
的每个新值开始一个新组。
该值通过 Rank_Column
.
4. REDUCE_PREV
拼图的最后一块:在 Rank_Column
= 1 上使用过滤器,我们确保每个“日历”行只得到一个“前一”行。
另外:通过 IF(ISNULL(...), ... , ...)
我们在三个计算列中模拟 COALESCE(...)
,恰当地命名为 FILL...
.
这就是该解决方案的具体细节。
“它在我的电脑上运行!” 可能是我能说的最好的了。
SELECT "CAL_YR", "CAL_PERIOD"
, "DAT_YR", "DAT_PER", "DAT_QTY"
, "FILL_YR", "FILL_QTY", "FILL_PER"
FROM "_SYS_BIC"."scratch/QTY_FILLUP"
ORDER BY "CAL_YR" asc, "CAL_PERIOD" asc;
/*
CAL_YR CAL_PERIOD DAT_YR DAT_PER DAT_QTY FILL_YR FILL_QTY FILL_PER
2,022 01 2,022 01 10 2,022 10 01
2,022 02 2,022 02 5 2,022 5 02
2,022 03 ? ? ? 2,022 5 02
2,022 04 2,022 04 10 2,022 10 04
2,022 05 2,022 05 7 2,022 7 05
2,022 06 ? ? ? 2,022 7 05
2,022 07 ? ? ? 2,022 7 05
2,022 08 ? ? ? 2,022 7 05
2,022 09 2,022 09 1 2,022 1 09
2,022 10 ? ? ? 2,022 1 09
2,022 11 ? ? ? 2,022 1 09
2,022 12 ? ? ? 2,022 1 09
*/