JD Edwards E1 (DB2) 的复杂 SQL 查询帮助

Complicated SQL query help for JD Edwards E1 (DB2)

首先承认我不是数据库或 SQL 专家。我知道基本的查询,也做过一些稍微复杂的查询,但这超出了我的知识范围。

背景

我的公司将 JD Edwards Enterprise One 用于他们的 ERP 应用程序。下面的table是本系统中实际的table表示的。为了简单起见,我在下面解释了它们。后端数据库是 AS/400 平台上的 DB2 运行。

Table 定义

Table:物品分类帐 (IL)
列数:

Business Unit
Work Center
Order #
Doc Type
Trans. Date
Qty Completed

Table: W/O 时间交易 (WOT)
列数:

Business Unit
Work Center
Order #
Hours Type
G/L Date
Hours Worked

备注:

示例数据

注意:对于糟糕的格式表示歉意,但似乎没有办法在这个场地很好地表示 table。

物品分类帐 (IL)

Business Unit   Work Center Order # Doc Type    Trans. Date Qty Completed
BU-1    WC-1    1   IC  8/7/20  20
BU-1    WC-1    1   IC  8/7/20  40
BU-1    WC-1    2   IC  8/7/20  10
BU-1    WC-2    3   IC  8/7/20  40
BU-1    WC-2    3   IC  8/7/20  10
BU-2    WC-4    6   IC  8/7/20  10
BU-2    WC-5    5   IC  8/7/20  60
BU-1    WC-1    2   IC  8/6/20  50
BU-1    WC-3    4   IC  8/6/20  30
BU-2    WC-5    5   IC  8/5/20  50
BU-2    WC-5    7   IC  8/1/20  20
BU-2    WC-5    8   IC  7/26/20 30
BU-2    WC-5    8   IC  7/25/20 50

W/O 时间交易 (WOT)

Business Unit   Work Center Order # Hours Type  G/L Date    Hours Worked
BU-2    WC-4    6   3   8/8/20  7.4
BU-1    WC-1    1   3   8/7/20  3.92
BU-1    WC-2    3   3   8/7/20  8
BU-1    WC-2    3   3   8/7/20  7
BU-1    WC-3    4   3   8/7/20  6.2
BU-2    WC-4    6   3   8/7/20  1.1
BU-1    WC-1    2   3   8/6/20  1.57
BU-2    WC-5    7   3   8/1/20  3.9
BU-2    WC-5    8   3   7/25/20 11.3

注意:在时间交易 table 中没有订单 # 5 的条目。

目标

目标 1:

我们正在努力获取工作时间和完成数量,按业务单位(例如 BU-1)和工作中心(例如 WC-1)分组,按周汇总(未来:添加其他时间范围,例如按个月)。

需要注意的重要事项是,在项目分类帐中的给定日期可能有多个完成,并且在工作时间的时间交易中可能有更少(有时只有一个)的条目数对应于那些完成。通常情况下,工作时间条目可能要到第二天才能发布(这是一个 24x7 轮班操作),在这种情况下,相关事件(给定订单的完成和小时记录)在不同的日子。

如果我们将这两个 table 的数据合并在一起,其中订单号是共同的领带:

注意:我是手动组装的,所以可能会有错误。

Business Unit   Work Center Order # Date    Hours Worked    Qty Completed
BU-2    WC-4    6   8/8/20  7.4 null
BU-1    WC-1    1   8/7/20  3.92    60
BU-1    WC-1    2   8/7/20  null    10
BU-1    WC-2    3   8/7/20  15  50
BU-1    WC-3    4   8/7/20  6.2 null
BU-2    WC-4    6   8/7/20  1.1 10
BU-2    WC-5    5   8/7/20  null    60
BU-1    WC-1    2   8/6/20  1.57    50
BU-1    WC-3    4   8/6/20  null    30
BU-2    WC-5    5   8/5/20  null    50
BU-2    WC-5    7   8/1/20  3.9 20
BU-2    WC-5    8   7/26/20 null    30
BU-2    WC-5    8   7/25/20 11.3    50

现在,按业务单位、工作中心分组并按周汇总:

Week    Business Unit   Work Center Hours Worked    Qty Completed
8/2/20 – 8/8/20             
    BU-2    WC-4    8.5 10
    BU-1    WC-1    5.49    120
    BU-1    WC-2    15  50
    BU-1    WC-3    6.2 30
    BU-2    WC-5    0   50
7/26/20 – 8/1/20                
    BU-2    WC-5    3.9 50
7/19/20 – 7/25/20               
    BU-2    WC-5    11.3    50

我不知道实现此结果的正确 SQL 查询。我认为这需要一个完整的外部连接,但我尝试过的一切似乎都会为结果集产生某种笛卡尔积,而这只是合并来自两个 table 的数据的第一步在一起,先不管最后的聚合和分组。

任何有关如何编写查询(或可能是多个查询?)以实现此类结果的帮助和建议,我们将不胜感激。

更新 (8/14/20):

我已尝试根据 https://whosebug.com/users/10418264/mark-barinstein (Mark Ba​​rinstein) 的建议实施查询。我已经分析了建议的查询,我想我大部分都理解了。

我正在努力将 JD Edwards Julian 日期转换为可用于计算一年中的星期几的表格。这是可能的最新尝试。请注意,此处使用的是实际的 table 和列名。

SELECT
  COALESCE(ILG.Week, WOG.Week) AS WEEK,
  COALESCE(ILG.BU, WOG.BU) AS BU,
  COALESCE(ILG.WC, WOG.WC) AS WC,
  COALESCE(WOG.Hours, 0) AS HOURS,
  COALESCE(ILG.Qty, 0) AS QTY
FROM
  (
    SELECT
      F31122.WTMMCU AS BU,
      F31122.WTMCU AS WC,
      WEEK(DATE(CAST(1900 + F31122.WTDGL/1000 AS CHAR(4)) || '-01-01') + (MOD(F31122.WTDGL, 1000) - 1) DAYS) AS Week,
      SUM(F31122.WTHRW) AS Hours
    FROM PROD2DTA.F31122 AS F31122
    WHERE
      (F31122.WTTYR IN ('3')) AND
      (F31122.WTDGL BETWEEN 120200 AND 120201)
    GROUP BY
      F31122.WTMMCU,
      F31122.WTMCU
  ) WOG
FULL JOIN
  (
    SELECT
      F4111.ILMCU AS BU,
      F4111.ILLOCN AS WC,
      WEEK(DATE(CAST(1900 + F4111.ILTRDJ/1000 AS CHAR(4)) || '-01-01') + (MOD(F4111.ILTRDJ, 1000) - 1) DAYS) AS Week,
      SUM(F4111.ILTRQT) AS Qty
    FROM PROD2DTA.F4111 AS F4111
    WHERE
      (F4111.ILDCT IN ('IC')) AND
      (F4111.ILTRDJ BETWEEN 120200 AND 120201)
    GROUP BY
      F4111.ILMCU,
      F4111.ILLOCN
  ) ILG
ON ILG.BU = WOG.BU AND ILG.WC = WOG.WC AND ILG.WEEK = WOG.WEEK
ORDER BY 1 DESC, 2, 3

有没有办法简化将 JDE Julian 日期转换为周数的逻辑?我明白正在做什么,但希望我能把它分解成一个函数并调用它。

不过我仍然遇到错误:

[SQL0122] Column WTDGL or expression in SELECT list not valid. (JdbcException)

不同的问题:可以在 GROUP BY 子句中使用列“别名”(例如 BU 而不是 F4111.ILMCU)吗?这将使它更具可读性。

试试这个:

SELECT
  COALESCE(ILG.WEEK, WOG.WEEK) AS WEEK
, COALESCE(ILG.BU, WOG.BU) AS BU
, COALESCE(ILG.WC, WOG.WC) AS WC
, COALESCE(WOG.Hours, 0) AS HOURS
, COALESCE(ILG.Qty, 0) AS QTY
FROM
(
SELECT BU, WC, WEEK(TO_DATE(GL_Date, 'MM/DD/YY')) AS Week, SUM(Hours) AS Hours
FROM WO
GROUP BY BU, WC, WEEK(TO_DATE(GL_Date, 'MM/DD/YY'))
) WOG
FULL JOIN
(
SELECT 
  BU, WC
, WEEK(TO_DATE(Trans_Date, 'MM/DD/YY')) AS Week
, SUM(Qty) AS Qty
FROM IL
GROUP BY BU, WC, WEEK(TO_DATE(Trans_Date, 'MM/DD/YY'))
) ILG ON ILG.BU = WOG.BU AND ILG.WC = WOG.WC AND ILG.WEEK = WOG.WEEK
ORDER BY 1 DESC, 2, 3

db<>fiddle link 测试一下。