我应该为此使用 SQL 完全外部连接吗?
Should I use an SQL full outer join for this?
考虑以下 table:
Table答:
DOC_NUM
DOC_TYPE
RELATED_DOC_NUM
NEXT_STATUS
...
Table乙:
DOC_NUM
DOC_TYPE
RELATED_DOC_NUM
NEXT_STATUS
...
DOC_TYPE
和 NEXT_STATUS
列在两个 table 之间具有不同的含义,尽管 NEXT_STATUS = 999
在两者中都表示“关闭”。此外,在某些情况下,每个 table 中都会有一条记录,并引用其他 table 中的相应条目(即 RELATED_DOC_NUM
列)。
我正在尝试创建一个查询,该查询将从满足以下条件的两个 table 中获取数据:
A.RELATED_DOC_NUM = B.DOC_NUM
A.DOC_TYPE = "ST"
B.DOC_TYPE = "OT"
A.NEXT_STATUS < 999 OR B.NEXT_STATUS < 999
A.DOC_TYPE = "ST"
表示将库存从一个工厂转移到另一个工厂的转移订单。 B.DOC_TYPE = "OT"
表示在收货工厂相应接收转移库存。
我们想从 table 中获取记录,其中有一个 ST/OT 对,其中一个或两个条目 not 关闭(即 NEXT_STATUS < 999
).
我假设我需要使用 FULL OUTER 联接来完成此操作。如果这是错误的假设,请让我知道我应该怎么做。
更新 (11/30/2021):
我相信@Caius Jard 是正确的,因为这不需要是外部连接。应该总是有一对 ST/OT。
据此,我编写了如下查询:
SELECT <columns>
FROM A LEFT JOIN B
ON
A.RELATED_DOC_NUM = B.DOC_NUM
WHERE
A.DOC_TYPE IN ('ST') AND
B.DOC_TYPE IN ('OT') AND
(A.NEXT_STATUS < 999 OR B.NEXT_STATUS < 999)
这有意义吗?
更新 2 (11/30/2021):
实际情况是,这些是 JD Edwards ERP 应用程序正在使用的 DB2 数据库 table。我知道要查看 table 定义的唯一方法是使用网站 http://www.jdetables.com/,输入 table ID 并点击 return 到 运行 搜索.它返回有关 table 及其列的大量信息。
Table A 真的是 F4211
而 table B 真的是 F4311
.
现在,我已简化查询以使其简单并将变量保持在最低限度。这是我目前拥有的:
SELECT CAST(F4211.SDDOCO AS VARCHAR(8)) AS SO_NUM,
F4211.SDRORN AS RELATED_PO,
F4211.SDDCTO AS SO_DOC_TYPE,
F4211.SDNXTR AS SO_NEXT_STATUS,
CAST(F4311.PDDOCO AS VARCHAR(8)) AS PO_NUM,
F4311.PDRORN AS RELATED_SO,
F4311.PDDCTO AS PO_DOC_TYPE,
F4311.PDNXTR AS PO_NEXT_STATUS
FROM PROD2DTA.F4211 AS F4211
INNER JOIN PROD2DTA.F4311 AS F4311
ON F4211.SDRORN = CAST(F4311.PDDOCO AS VARCHAR(8))
WHERE F4211.SDDCTO IN ( 'ST' )
AND F4311.PDDCTO IN ( 'OT' )
故事的另一部分是我正在使用一个报告包,它允许您定义数据的“虚拟”视图。虚拟视图允许报表开发人员指定要使用的 SQL。这是我使用 SQL 的应用程序。当我设置 SQL 时,必须执行一个验证步骤。如果 SQL 得到验证,它将 return 一组有限的结果。
当我输入上面的查询并验证它时,它说没有结果,这是没有意义的。我猜是数据转换导致了这个问题,但不确定。
更新 3 (11/30/2021):
故事又转折了。相关文档编号不仅定义为字符串值,而且包含前导零。在 table 中都是如此。主文档编号(在 table 中)被定义为数值,因此没有前导零。我不知道为什么那些开发 JDE 的人会这样做,但就是这样。
所以,在满足条件的两个 table 之间有 条匹配记录,但我认为我没有得到任何结果,因为当我转换数字时对于一个字符串,它不匹配,因为一个值是 "12345"
,而另一个是 "00012345"
.
我可以在进行相等检查之前用零填充数字 -> 字符串值吗?
更新 4 (12/2/2021):
通过将数字文档编号转换为左零填充字符串,最终能够使查询正常工作。
SELECT <columns>
FROM PROD2DTA.F4211 AS F4211
INNER JOIN PROD2DTA.F4311 AS F4311
ON F4211.SDRORN = RIGHT(CONCAT('00000000', CAST(F4311.PDDOCO AS VARCHAR(8))), 8)
WHERE F4211.SDDCTO IN ( 'ST' )
AND F4311.PDDCTO IN ( 'OT' )
AND ( F4211.SDNXTR < 999
OR F4311.PDNXTR < 999 )
您应该按如下方式编写查询:
SELECT <columns>
FROM A INNER JOIN B
ON
A.RELATED_DOC_NUM = B.DOC_NUM
WHERE
A.DOC_TYPE IN ('ST') AND
B.DOC_TYPE IN ('OT') AND
(A.NEXT_STATUS < 999 OR B.NEXT_STATUS < 999)
LEFT join 是 OUTER join 的一种; LEFT JOIN 通常是 LEFT OUTER JOIN 的缩写)。 OUTER 表示“一侧可能在每一列中都有空值,因为没有匹配项”。最关键的是,问题中发布的代码(使用 LEFT JOIN,但随后有 WHERE some_column_from_the_right_table = some_value
)作为 INNER 连接运行,因为 LEFT OUTER 进程插入的任何 NULL,然后被 WHERE 子句取消
有关我如何解决“数据转换或映射”错误的详细信息,请参阅更新 4。
考虑以下 table:
Table答:
DOC_NUM
DOC_TYPE
RELATED_DOC_NUM
NEXT_STATUS
...
Table乙:
DOC_NUM
DOC_TYPE
RELATED_DOC_NUM
NEXT_STATUS
...
DOC_TYPE
和 NEXT_STATUS
列在两个 table 之间具有不同的含义,尽管 NEXT_STATUS = 999
在两者中都表示“关闭”。此外,在某些情况下,每个 table 中都会有一条记录,并引用其他 table 中的相应条目(即 RELATED_DOC_NUM
列)。
我正在尝试创建一个查询,该查询将从满足以下条件的两个 table 中获取数据:
A.RELATED_DOC_NUM = B.DOC_NUM
A.DOC_TYPE = "ST"
B.DOC_TYPE = "OT"
A.NEXT_STATUS < 999 OR B.NEXT_STATUS < 999
A.DOC_TYPE = "ST"
表示将库存从一个工厂转移到另一个工厂的转移订单。 B.DOC_TYPE = "OT"
表示在收货工厂相应接收转移库存。
我们想从 table 中获取记录,其中有一个 ST/OT 对,其中一个或两个条目 not 关闭(即 NEXT_STATUS < 999
).
我假设我需要使用 FULL OUTER 联接来完成此操作。如果这是错误的假设,请让我知道我应该怎么做。
更新 (11/30/2021):
我相信@Caius Jard 是正确的,因为这不需要是外部连接。应该总是有一对 ST/OT。
据此,我编写了如下查询:
SELECT <columns>
FROM A LEFT JOIN B
ON
A.RELATED_DOC_NUM = B.DOC_NUM
WHERE
A.DOC_TYPE IN ('ST') AND
B.DOC_TYPE IN ('OT') AND
(A.NEXT_STATUS < 999 OR B.NEXT_STATUS < 999)
这有意义吗?
更新 2 (11/30/2021):
实际情况是,这些是 JD Edwards ERP 应用程序正在使用的 DB2 数据库 table。我知道要查看 table 定义的唯一方法是使用网站 http://www.jdetables.com/,输入 table ID 并点击 return 到 运行 搜索.它返回有关 table 及其列的大量信息。
Table A 真的是 F4211
而 table B 真的是 F4311
.
现在,我已简化查询以使其简单并将变量保持在最低限度。这是我目前拥有的:
SELECT CAST(F4211.SDDOCO AS VARCHAR(8)) AS SO_NUM,
F4211.SDRORN AS RELATED_PO,
F4211.SDDCTO AS SO_DOC_TYPE,
F4211.SDNXTR AS SO_NEXT_STATUS,
CAST(F4311.PDDOCO AS VARCHAR(8)) AS PO_NUM,
F4311.PDRORN AS RELATED_SO,
F4311.PDDCTO AS PO_DOC_TYPE,
F4311.PDNXTR AS PO_NEXT_STATUS
FROM PROD2DTA.F4211 AS F4211
INNER JOIN PROD2DTA.F4311 AS F4311
ON F4211.SDRORN = CAST(F4311.PDDOCO AS VARCHAR(8))
WHERE F4211.SDDCTO IN ( 'ST' )
AND F4311.PDDCTO IN ( 'OT' )
故事的另一部分是我正在使用一个报告包,它允许您定义数据的“虚拟”视图。虚拟视图允许报表开发人员指定要使用的 SQL。这是我使用 SQL 的应用程序。当我设置 SQL 时,必须执行一个验证步骤。如果 SQL 得到验证,它将 return 一组有限的结果。
当我输入上面的查询并验证它时,它说没有结果,这是没有意义的。我猜是数据转换导致了这个问题,但不确定。
更新 3 (11/30/2021):
故事又转折了。相关文档编号不仅定义为字符串值,而且包含前导零。在 table 中都是如此。主文档编号(在 table 中)被定义为数值,因此没有前导零。我不知道为什么那些开发 JDE 的人会这样做,但就是这样。
所以,在满足条件的两个 table 之间有 条匹配记录,但我认为我没有得到任何结果,因为当我转换数字时对于一个字符串,它不匹配,因为一个值是 "12345"
,而另一个是 "00012345"
.
我可以在进行相等检查之前用零填充数字 -> 字符串值吗?
更新 4 (12/2/2021):
通过将数字文档编号转换为左零填充字符串,最终能够使查询正常工作。
SELECT <columns>
FROM PROD2DTA.F4211 AS F4211
INNER JOIN PROD2DTA.F4311 AS F4311
ON F4211.SDRORN = RIGHT(CONCAT('00000000', CAST(F4311.PDDOCO AS VARCHAR(8))), 8)
WHERE F4211.SDDCTO IN ( 'ST' )
AND F4311.PDDCTO IN ( 'OT' )
AND ( F4211.SDNXTR < 999
OR F4311.PDNXTR < 999 )
您应该按如下方式编写查询:
SELECT <columns>
FROM A INNER JOIN B
ON
A.RELATED_DOC_NUM = B.DOC_NUM
WHERE
A.DOC_TYPE IN ('ST') AND
B.DOC_TYPE IN ('OT') AND
(A.NEXT_STATUS < 999 OR B.NEXT_STATUS < 999)
LEFT join 是 OUTER join 的一种; LEFT JOIN 通常是 LEFT OUTER JOIN 的缩写)。 OUTER 表示“一侧可能在每一列中都有空值,因为没有匹配项”。最关键的是,问题中发布的代码(使用 LEFT JOIN,但随后有 WHERE some_column_from_the_right_table = some_value
)作为 INNER 连接运行,因为 LEFT OUTER 进程插入的任何 NULL,然后被 WHERE 子句取消
有关我如何解决“数据转换或映射”错误的详细信息,请参阅更新 4。