2010-11-03 60 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';