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 的列数比显示的多得多
这里。
- 查询需要过滤项目分类帐,以便文档类型 =
“集成电路”。
- 查询需要过滤时间交易,例如小时类型
=“3”。
示例数据
注意:对于糟糕的格式表示歉意,但似乎没有办法在这个场地很好地表示 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 Barinstein) 的建议实施查询。我已经分析了建议的查询,我想我大部分都理解了。
我正在努力将 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 测试一下。
首先承认我不是数据库或 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 的列数比显示的多得多 这里。
- 查询需要过滤项目分类帐,以便文档类型 = “集成电路”。
- 查询需要过滤时间交易,例如小时类型 =“3”。
示例数据
注意:对于糟糕的格式表示歉意,但似乎没有办法在这个场地很好地表示 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 Barinstein) 的建议实施查询。我已经分析了建议的查询,我想我大部分都理解了。
我正在努力将 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 测试一下。