SAP HANA SQL 比较行项目
SAP HANA SQL to compare line-items
问题:
我如何才能在文档编号中找到与其他文档编号至少匹配 X 百分比(例如 >=50%)的材料?
创建 TABLE:
CREATE COLUMN TABLE "SCHEMA"."MYTABLE"
(
"DOCUMENT" NVARCHAR(10) DEFAULT '' NOT NULL ,
"POSNR" NVARCHAR(6) DEFAULT '000000' NOT NULL ,
"MATERIAL" NVARCHAR(40) DEFAULT '' NOT NULL,
PRIMARY KEY (
"DOCUMENT",
"POSNR")
) UNLOAD PRIORITY 5 AUTO MERGE
;
插入数据:
INSERT INTO MYTABLE VALUES (100, '10', 'R3');
INSERT INTO MYTABLE VALUES (100, '20', '7000000');
INSERT INTO MYTABLE VALUES (100, '30', '7000010');
INSERT INTO MYTABLE VALUES (100, '40', '7000011');
INSERT INTO MYTABLE VALUES (100, '50', '7000160');
INSERT INTO MYTABLE VALUES (200, '10', 'SW');
INSERT INTO MYTABLE VALUES (200, '20', '7000000');
INSERT INTO MYTABLE VALUES (200, '30', '7000010');
INSERT INTO MYTABLE VALUES (200, '40', '7000011');
INSERT INTO MYTABLE VALUES (200, '50', '7000160');
INSERT INTO MYTABLE VALUES (200, '60', '7000036');
INSERT INTO MYTABLE VALUES (200, '70', '7000040');
INSERT INTO MYTABLE VALUES (200, '80', '7000066');
INSERT INTO MYTABLE VALUES (200, '90', '7000068');
INSERT INTO MYTABLE VALUES (300, '01', '7000160');
INSERT INTO MYTABLE VALUES (300, '11', '7000011');
INSERT INTO MYTABLE VALUES (400, '10', '7000033');
INSERT INTO MYTABLE VALUES (400, '20', '7000034');
INSERT INTO MYTABLE VALUES (400, '50', '7000068');
INSERT INTO MYTABLE VALUES (400, '60', '7000079');
确实不用游标也能解决
with doc_elements
(document, material, material_cnt)
as (select distinct
document
, material
, count( *) OVER
(PARTITION BY document) as MATERIAL_CNT
from
mytable
)
, matched_materials
(document_a, material, material_b_cnt, document_b, match_cnt)
as (select
side_a.document as document_a
, side_a.material
, side_b.material_cnt as material_a_cnt
, side_b.document doc_b
, count(*) OVER
(PARTITION BY side_a.document, side_b.document) as match_cnt
from
doc_elements side_a
left outer join doc_elements side_b
on side_a.material = side_b.material
and side_a.document != side_b.document
where
side_b.document IS NOT NULL
)
select distinct
document_a
--, material
, document_b
, material_b_cnt
, match_cnt
, round((100/material_b_cnt)*match_cnt, 2) as match_pct
from
matched_materials
order by
document_a
, document_b;
这条语句returns:
DOCUMENT_A|DOCUMENT_B|MATERIAL_B_CNT|MATCH_CNT|MATCH_PCT|
----------|----------|--------------|---------|---------|
100 |200 | 9| 4| 44.44|
100 |300 | 2| 2| 100|
200 |100 | 6| 4| 66.67|
200 |300 | 2| 2| 100|
200 |400 | 4| 1| 25|
300 |100 | 6| 2| 33.33|
300 |200 | 9| 2| 22.22|
400 |200 | 9| 1| 11.11|
为简单起见,我将 R3
和 SW
视为常规 materials。
输出仅包含具有至少一个 material 匹配项的文档映射(参见 matched_material
通用 table 表达式中的 side_b.document IS NOT NULL
条件)。
请注意,评论中的结果规范包含错误:
文档 400 没有匹配项,因为 material 7000068 不是文档 100 的 material 的一部分。
我把这个问题作为一个提示,更广泛地写了这个解决方案,还包括对查询性能和调整选项的审查。
见
https://lbreddemann.org/matchmaker/ 和
https://lbreddemann.org/matchmaker-quick-quick/
为此。
问题: 我如何才能在文档编号中找到与其他文档编号至少匹配 X 百分比(例如 >=50%)的材料?
创建 TABLE:
CREATE COLUMN TABLE "SCHEMA"."MYTABLE"
(
"DOCUMENT" NVARCHAR(10) DEFAULT '' NOT NULL ,
"POSNR" NVARCHAR(6) DEFAULT '000000' NOT NULL ,
"MATERIAL" NVARCHAR(40) DEFAULT '' NOT NULL,
PRIMARY KEY (
"DOCUMENT",
"POSNR")
) UNLOAD PRIORITY 5 AUTO MERGE
;
插入数据:
INSERT INTO MYTABLE VALUES (100, '10', 'R3');
INSERT INTO MYTABLE VALUES (100, '20', '7000000');
INSERT INTO MYTABLE VALUES (100, '30', '7000010');
INSERT INTO MYTABLE VALUES (100, '40', '7000011');
INSERT INTO MYTABLE VALUES (100, '50', '7000160');
INSERT INTO MYTABLE VALUES (200, '10', 'SW');
INSERT INTO MYTABLE VALUES (200, '20', '7000000');
INSERT INTO MYTABLE VALUES (200, '30', '7000010');
INSERT INTO MYTABLE VALUES (200, '40', '7000011');
INSERT INTO MYTABLE VALUES (200, '50', '7000160');
INSERT INTO MYTABLE VALUES (200, '60', '7000036');
INSERT INTO MYTABLE VALUES (200, '70', '7000040');
INSERT INTO MYTABLE VALUES (200, '80', '7000066');
INSERT INTO MYTABLE VALUES (200, '90', '7000068');
INSERT INTO MYTABLE VALUES (300, '01', '7000160');
INSERT INTO MYTABLE VALUES (300, '11', '7000011');
INSERT INTO MYTABLE VALUES (400, '10', '7000033');
INSERT INTO MYTABLE VALUES (400, '20', '7000034');
INSERT INTO MYTABLE VALUES (400, '50', '7000068');
INSERT INTO MYTABLE VALUES (400, '60', '7000079');
确实不用游标也能解决
with doc_elements
(document, material, material_cnt)
as (select distinct
document
, material
, count( *) OVER
(PARTITION BY document) as MATERIAL_CNT
from
mytable
)
, matched_materials
(document_a, material, material_b_cnt, document_b, match_cnt)
as (select
side_a.document as document_a
, side_a.material
, side_b.material_cnt as material_a_cnt
, side_b.document doc_b
, count(*) OVER
(PARTITION BY side_a.document, side_b.document) as match_cnt
from
doc_elements side_a
left outer join doc_elements side_b
on side_a.material = side_b.material
and side_a.document != side_b.document
where
side_b.document IS NOT NULL
)
select distinct
document_a
--, material
, document_b
, material_b_cnt
, match_cnt
, round((100/material_b_cnt)*match_cnt, 2) as match_pct
from
matched_materials
order by
document_a
, document_b;
这条语句returns:
DOCUMENT_A|DOCUMENT_B|MATERIAL_B_CNT|MATCH_CNT|MATCH_PCT|
----------|----------|--------------|---------|---------|
100 |200 | 9| 4| 44.44|
100 |300 | 2| 2| 100|
200 |100 | 6| 4| 66.67|
200 |300 | 2| 2| 100|
200 |400 | 4| 1| 25|
300 |100 | 6| 2| 33.33|
300 |200 | 9| 2| 22.22|
400 |200 | 9| 1| 11.11|
为简单起见,我将 R3
和 SW
视为常规 materials。
输出仅包含具有至少一个 material 匹配项的文档映射(参见 matched_material
通用 table 表达式中的 side_b.document IS NOT NULL
条件)。
请注意,评论中的结果规范包含错误:
文档 400 没有匹配项,因为 material 7000068 不是文档 100 的 material 的一部分。
我把这个问题作为一个提示,更广泛地写了这个解决方案,还包括对查询性能和调整选项的审查。
见
https://lbreddemann.org/matchmaker/ 和
https://lbreddemann.org/matchmaker-quick-quick/
为此。