【问题标题】:SQL DB2 : How to JOIN dynamicaly 2 tables using "running total calculations"SQL DB2:如何使用“运行总计算”动态连接 2 个表
【发布时间】:2020-06-02 16:01:59
【问题描述】:

我正在服务器上学习 SQL:IBM V7R1M0、DB2。

我正在尝试构建 SQL 报告。 找了几天类似的例子,我在知识的海洋里推出了这个瓶子……

上下文: 商店向仓库索取货物。 这些货物是在托盘上挑选的。 这些托盘在装载到卡车之前将被放置在临时通道上。

规则 1:我们只希望一个商店的货盘在集结通道上(我们不想混合来自不同商店的货盘)

规则 2:商店将占用附近的集结通道。

规则 3:暂存通道按那里的 ID 排序(有间隙)

表 1:

|-----|-----|-----------------|
| ID  |store|pallet_estimation|
|-----|-----|-----------------|
| 1   | A   | 35              |
| 2   | C   |  2              |
| 3   | B   | 30              |
|-----|-----|-----------------|

SELECT * FROM (
    VALUES (1, 'A', 35), (2, 'C', 2), (3, 'B', 30)
          ) T1(ID, store, pallet_estimation) 

表 2:

|---------------|---------------|
|ID_staging_lane|pallet_capacity|
|---------------|---------------|
| 201           | 10            |
| 202           | 10            |
| 204           | 30            |
| 205           | 40            |
| 208           | 30            |
| 210           | 30            |
|---------------|---------------|

SELECT * FROM(
  VALUES (201, 10), (202, 10), (204, 30), (205, 40), (208, 30), (210, 30)
     ) T2(ID_staging_lane, pallet_capacity)

预期结果:

|-----------|--------|--------------------|---------------|------------------|
|T1_sequence|T1_store|T1_pallet_estimation|T2_staging_lane|T2_pallet_capacity|
|-----------|--------|--------------------|---------------|------------------|
| 1         | A      | 35                 | 201           | 10               |
| 1         | A      | 35                 | 202           | 10               |
| 1         | A      | 35                 | 204           | 30               |
| 2         | C      |  2                 | 205           | 40               |
| 3         | B      | 30                 | 208           | 30               |
|-----------|--------|--------------------|---------------|------------------|

谢谢你,Charles,抽出时间。 我会努力改善我的需求。

如果需要,我想按照顺序将pallet_estimation 拆分/划分到几个分段通道上

例子:

For store A which has 35 pallets, 
I want to use staging lane 201 then it remains 35 - 10 = 25 , 
then I want to use staging lane 202 then it remains 25 - 10 = 15, 
then I want to use staging lane 204 then it remains 15 - 30 = -15

then I want to continue with the store C on the next staging lane 205 then it remains 2 - 40 = -38

then I want to continue with the store B on the next staging lane 208 then it remains 30 - 30 = 0

您将如何开始构建它? - 有窗口功能?总和()超过() - 使用递归 SQL 吗?声明获取 - 是否可以在 SQL 中构建动态 JOIN ? - 其他想法?

提前致谢,

雷诺

【问题讨论】:

    标签: sql db2-400


    【解决方案1】:

    首先,v7r1 已经很老了...确切地说是 10 年...

    其次,我不明白您要加入什么...我看不出任何可以解释为什么商店 A 最终在您的结果中有 3 行的原因。

    第三,在任何 RDBMS 中都没有“动态连接”之类的东西。您可以有一个动态语句,其中可能包括一个联接。或者你可以有一个静态语句,它也可以包括一个连接。对于 IBM i 上的 Db2,只有将语句合并到 RPG/COLBOL 程序或 SQL 存储过程/函数中才重要。

    说了这么多,现在让我向您介绍公用表表达式 (CTE)。与嵌套表表达式 (NTE) 基本相同,但 IMO 更易于遵循,并且 CTE 在 i 上也比 NTE 具有性能优势。

    with T1 as (
      SELECT * FROM (
        VALUES (1, 'A', 35), (2, 'C', 2), (3, 'B', 30)
              ) T1(ID, store, pallet_estimation)
    ), T2 as (
    SELECT * FROM(
      VALUES (201, 10), (202, 10), (204, 30), (205, 40), (208, 30), (210, 30)
         ) T2(ID_staging_lane, pallet_capacity)
    ), fitment as (
    select T1.*, T2.*, row_number() OVER(partition by ID_STAGING_LANE) as rowNbr
    from T1 join T2 on pallet_estimation <= pallet_capacity
    )
    select * from fitment where rowNbr = 1;
    

    with T1 as (&lt;select statement&gt;) 是公用表表达式; T2fitment 也是如此。 with 关键字仅用于第一个 CTE。

    fitment CTE 连接 T1 和 T2,根据哪个估计值适合车道描述,为每个可能性分配一个 row_number。最终的选择首先适合每条车道。

    CTE 的好处是您可以轻松构建它们并在执行过程中查看结果。您可以随时添加select * from MYCTE 并查看您目前拥有的内容。

    请注意,如图所示,一个 CTE 可以引用另一个 CTE。 (fitment 引用 T1T2

    编辑
    您需要使用、在结果集中向前或向后看的函数被命名为LAG()LEAD()。它们是 Db2 for i 中内置的 OLAP functionality 的一部分。不幸的是,它们是在 7.3 中添加的。

    您将需要使用用户定义的函数 (UDF) 推出您自己的版本,该函数使用所谓的 scatchpad 在每行的函数调用之间保存数据。

    我找到了一篇非常古老的文章Scribble on SQL's Scratchpad,展示了如何在 RPG 中使用便签本。您也可以在 SQL 定义的 UDF 中使用它。

    做一些谷歌搜索,看看你是否可以开始。如果您遇到问题,请在此处创建一个新问题。 (或查看Midrange mailing lists

    【讨论】:

    • 你好查尔斯,谢谢你的时间。
    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 2020-03-01
    • 1970-01-01
    相关资源
    最近更新 更多