DB2 - 为字符串中的字符获取多个位置的方法

时间:2012-10-11 17:36:20

标签: sql db2

所以我很高兴能够使用一个非常古老的数据库,这个数据库显然是在标准化发明之前设置的。我被问到是否能想出办法让它正常工作。

第一个表实际上有一个真正的主键。 例如:

ID, Reason
--- ----------
 1, Write off
 2, Overage
 3, OLH

问题出在另一张桌子上......

CustomerNum, JobNum, Reasons
------------ ------- ---------------------
      42351,     46, X
      32313,    456,    X
      85472,     13,   X    X

这些表如何加入他们的系统?是的,X在线上的位置。因此,如果X位于第一个位置,那么原因是1,第二个位置,原因2,依此类推。它本质上是一个平面阵列。如果他们将它限制在每行1 X ......(LOCATE('X', REASONS) as XINDEX),那实际上并不会很糟糕,但事实并非如此。从理论上讲,每行可以检查21种可能的X.

所以我必须向他们提出如何使其发挥作用的建议 我的第一个建议之一是创建一个单独的表并对表进行规范化,但是我不知道它会有多好,或者他们是否愿意改变他们的系统。
所以,我还想建议类似于存储过程的东西,它能够遍历每一行并返回索引,就好像它们在一个单独的表中一样。

我不知道这是否可能,但我很有希望。

修改

所以是的,我真的要推送链接表 这是我从建议中得到的另一种选择:

Select tblCustomers.*, 
CASE WHEN SUBSTRING(Reasons,1,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 1)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,2,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 2)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,3,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 3)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,4,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 4)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,5,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 5)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,6,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 6)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,7,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 7)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,8,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 8)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,9,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 9)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,10,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 10)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,11,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 11)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,12,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 12)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,13,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 13)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,14,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 14)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,15,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 15)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,16,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 16)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,17,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 17)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,18,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 18)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,19,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 19)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,20,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 20)) || ', ' ELSE '' END 
|| CASE WHEN SUBSTRING(Reasons,21,1) = 'X' THEN RTRIM((SELECT Reason FROM tblReasons WHERE ID = 21)) || ', ' ELSE '' END AS XPOS 
From tblCustomers

我将不得不玩Marlin的建议,看看它有多精简它,但我对此查询的一个看法是,它显示了当前布局是多么荒谬,以及为什么要更改它

2 个答案:

答案 0 :(得分:1)

我要做的第一件事就是为X的每个可能位置创建一个新列(所以如果有10个位置 - > 10个新cols)并给这些列提供有意义的名称。那么你可以更容易地编写查询......

答案 1 :(得分:1)

我真的推销新的链接表,但这里要么是存储过程的主要内容,要么是填充链接表的方式:

SELECT Customers.CustomerNum, Reasons.ID
FROM Customers, Reasons
WHERE SUBSTR(Customers.Reasons, Reasons.ID, 1) = 'X'