【发布时间】:2019-12-11 03:26:56
【问题描述】:
您好,我对 Teradata SQL 中的表连接有疑问。所以我有一个交易表(T1)和另一个国家映射表(M1)来连接在一起。
在事务表(T1)中,还包括(对于表连接):(i)。销售组织代码; (二)。销往国家代码
表 T1:
SalesOrg Code Sold-To Country Cd Product Code Trans. Date Revenue Amt
0001 ES P001 01/08/2019 199.00
0002 IE P002 02/08/2019 399.00
0002 FR P003 02/08/2019 299.00
0002 IT P005 02/08/2019 599.00
0002 BE P002 02/08/2019 399.00
0002 LU P005 02/08/2019 599.00
0002 NL P001 02/08/2019 199.00
对于国家映射表(M1),如下所示:
SalesOrg Code Reporting Country Sold-To Country Code Sold-To Country Name
0001 Spain null null
0002 UK IE Ireland
0002 UK FR France
0002 UK IT Italy
0002 Netherlands Ex: NOT: FR IE IT
.......
我想要实现的是根据以下条件加入两个表:
1)。如果 Sold-To Country Code 为空,则从
销售组织代码中的 T1(例如 #0001);
2)。如果 Sold-To Country Code 不为 NULL 且不包含“Ex”,则根据 SalesOrg Code 和 Sold-To Country Code 映射来自 T1 的交易;
3)。如果 Sold-To Country Code 包含“Ex”(表示排除),则从相同的 SalesOrg 代码映射 T1 交易,但不包括最后一列中指定的国家代码,如上例:NOT:FR IE IT。
对于#3 条件,我最终想将字符串文本 NOT: FR IE IT 中的值转换为列表,以便它可以在 JOIN 中使用,就像 NOT IN ('FR','IE','IT ')。
最终我想得到如下结果(最后的附加列 - 报告国家):
SalesOrg Code Sold-To Country Cd Product Code Trans. Date Revenue Amt Reporting Country
0001 ES P001 01/08/2019 199.00 Spain
0002 IE P002 02/08/2019 399.00 UK
0002 FR P003 02/08/2019 299.00 UK
0002 IT P005 02/08/2019 599.00 UK
0002 BE P002 02/08/2019 399.00 Netherlands
0002 LU P005 02/08/2019 599.00 Netherlands
0002 NL P001 02/08/2019 199.00 Netherlands
........
有更好的主意吗?
我尝试使用 STRTOK_SPLIT_TO_TABLE 将值 FR IE IT 转换为行,它确实可以创建这样的列表。但是,这不是唯一的情况,其他国家也有同样的情况,因此,我需要连接条件基于 M1 表中记录的每一行。
(
CASE WHEN M1.Sold_to_Country_Code LIKE 'Ex%') THEN (
SELECT DISTINCT TOKEN
FROM TABLE (STRTOK_SPLIT_TO_TABLE(1,
(SELECT DISTINCT
TRIM(BOTH FROM (SUBSTR(M1.Sold_to_Country_Name,INSTR(M1.Sold_to_Country_Name,' ')))) AS Exclude_Country
FROM M1
WHERE M1.Sold_to_Country_Code LIKE 'Ex%'
),' ')
RETURNS (OUTKEY INTEGER,
TOKENNUM INTEGER,
TOKEN VARCHAR(2) CHARACTER SET UNICODE)
) AS d )
END )
我在下面尝试过,但它无法正确映射,因为它将与荷兰的重复映射以及 Sold-To 国家代码 IE FR IT。
SELECT DISTINCT
T1.sales_org_cd,
M1.Reporting_Country,
M1.Sold_to_Country_Code,
OREPLACE(TRIM(BOTH FROM (SUBSTR(M1.Sold_to_Country_Name,INSTR(M1.Sold_to_Country_Name,' ')))),' ',',') AS SC,
T1.Country_Cd
FROM T1
FULL OUTER JOIN M1
ON T1.Sales_org_cd = M1.Sales_org_code
AND (
(M1.Sold_to_Country_Code IS NULL AND T1.Country_cd ?? (not sure for condition #1)
(M1.Sold_to_Country_Code IS NOT NULL AND M1.Sold_to_Country_Code NOT LIKE 'Ex%' AND T1.Country_cd=M1.Sold_to_Country_Code )
OR (T1.Country_cd IS NOT NULL AND M1.Sold_to_Country_Code LIKE 'Ex%' AND T1.Country_cd NOT IN (OREPLACE(TRIM(BOTH FROM (SUBSTR(M1.Sold_to_Country_Name,INSTR(M1.Sold_to_Country_Name,' ')))),' ',',')) )
)
WHERE T1.sales_org_cd IN ('0001','0002')
希望我的解释清楚。 不确定这些是否可以实现。感谢您提供任何意见或建议。
【问题讨论】:
-
请edit您的帖子正确使用降价来格式化您的所有代码示例/术语。
-
这是一次性加载吗?输入或更改新行的频率。此表的工作方式是错误的,如果您使用真正的关系模型,您应该将内容出售给其他表中的列
-
为什么不进行子字符串匹配以确保要匹配的值的两侧都存在分隔符,例如
POSITION(' '||T1.Country_cd||' ' IN M1.Sold_to_Country_Name||' ') > 0 -
@GordonLinoff 嗨,戈登。我只是在加入后添加了 T1 和所需的表。希望它更清楚。非常感谢您的帮助!
-
@Hogan 嗨,霍根,这不是一次性的事情,对于一些处于同样复杂情况的国家,地图故事需要不时更新我知道如果我列出所有对于向荷兰报告的其他国家/地区,它会起作用。但是,与 NOT IN(“国家列表”)方法相比,它需要更多的维护。因此,我正在尝试为此寻求任何可能的解决方案。谢谢你的帮助!:)
标签: sql teradata teradata-sql-assistant