2010-11-03 49 views
0

我需要筛选出一列中具有指定列表值中的值的SQL表中的行。简化表看起来像:(对不起,坏的格式,从来没有贴在这里)SQL从列表中筛选项

Error Codes  | Other Column 1 | Other Column 2 ... 

-------------------------------------------------- 
F010,F123,F345, | ......  | ..... 

F231,FC85,F904, | ......  | ..... 

FC432,F0425,NA, | ......  | ..... 

.... 

我第一次分裂错误代码柱得到各3个错误代码,这是一个逗号分隔值的字符串。然后,我需要在给定列表中筛选出具有全部三个错误代码的行,例如('F010','FC542','FB943')。我在Teradata数据库运行此,这是查询的一部分,但似乎并没有被列入名单中筛选出所有组合:

SELECT ... , 

CASE 
WHEN (substr(a.error_code, 1, position(',' in a.error_code)-1) in ('F010', 'FC542', 'FB012' 'FB943', 'NA') 

AND substr(a.error_code, 
       position(',' in a.error_code)+1, 
       position(',' in substr(a.error_code, position(',' in a.error_code)+1, Characters(a.error_code)-position(',' in a.error_code)))-1) in ('F010', 'FC542', 'FB012' 'FB943', 'NA') 

AND substr(a.error_code, 
      position(',' in a.error_code) + position(',' in substr(a.error_code, position(',' in a.error_code)+1, Characters(a.error_code)-position(',' in a.error_code)))+1, 
      Characters(a.error_code)-(position(',' in a.error_code) + position(',' in substr(a.error_code, position(',' in a.error_code)+1, Characters(a.error_code)-position(',' in a.error_code))))-1) in ('F010', 'FC542', 'FB012' 'FB943', 'NA')) 

THEN 'No' 

ELSE 'Yes' 

end Error_Module, 

... 
FROM Error_code_table a 

WHERE Error_Module = 'Yes' 

作为一个侧面,人物()函数是一样的作为长度()。

谢谢, 迈克

+2

正如Bob Jarvis所观察到的,单个字段中以逗号分隔的列表中的多个值使这变得更加困难。我会更进一步,并说如果完全可以避免的话,这绝不应该这样做 - 这违反了第一范式,完全违背所有关系设计原则。 – 2010-11-03 13:38:17

+0

我同意,不幸的是这是如何建立数据库,以及我必须处理的事情。 – Mike 2010-11-03 17:00:24

回答

1

包含在一列以逗号分隔的列表中有多个值,使这变得更加困难。如果可以重新编写这个任务,那么这个任务会更容易,因此每行只有一个错误代码。

我对Teradata并不熟悉,但看着Google,他们看起来很擅长分析和商业智能。因此,我希望他们有一些正则表达式功能可用,我认为这将是您开始寻找的好地方。例如,在Oracle中我会做像下面这样从一个字符串中提取错误代码:

SELECT TRIM(REGEXP_REPLACE(ERROR_CODES, '(.*),.*,.*', '\1')), 
     TRIM(REGEXP_REPLACE(ERROR_CODES, '.*,(.*),.*', '\1')), 
     TRIM(REGEXP_REPLACE(ERROR_CODES, '.*,.*,(.*)', '\1')) 
    INTO strErr1, strErr2, strErr3 
    FROM DUAL; 

好运。

+0

通过版本12,Teradata不支持正则表达式支持。它应该可以在Teradata 13或13.10中使用 – 2010-11-03 12:53:43

0

如果错误代码未出现在列表的开头,它将始终以,<error code>,的形式出现。

SELECT 
    CASE 
     WHEN substr(a.error_code, 1, position(',' in a.error_code) - 1) in ('F010', 'FC542', 'FB012', 'FB943', 'NA') 
      OR a.error_code LIKE ANY ('%,F010,%', '%,FC542,%', '%,FB012,%', '%,FB943,%', '%,NA,%') 
     THEN 'No' 
     ELSE 'Yes' 
    End Error_Module 
FROM Error_code_table a 
WHERE Error_Module = 'Yes';