2010-07-11 24 views
0

請幫我找到一個解決方案。我有一個像使用SQL2000將字段中的數據拆分爲行

ID Code  

1  123,456,789,12 
2  456,073   
3  69,76,56 

在表中的數據,我需要的代碼列表中排

ID Code     Ref 

1  123,456,789,12  123 

1  123,456,789,12  456 

1  123,456,789,12  789 

1  123,456,789,12  12 

2  456,073    456 

2  456,073    073 

3  69,76,56    69 

3  69,76,56    76 

3  69,76,56    56 

如何做到這一點的查詢命令?我將使用ref列中的值加入另一個表中的另一列。 感謝您的支持

回答

3

我的第一個建議是規範化您的數據庫。一列應包含一條信息。你的逗號分隔的值違反了這個規則,這就是爲什麼你面臨這樣的困難。因爲人們很少會採納這個建議,這裏有一個可能適合你的混合物。既然你加入這個到另一個表,你並不真的需要每個值在自己的列分離出來,你只需要能夠找到在你列一個匹配值:

SELECT 
    T1.id, 
    T1.code, 
    T2.ref 
FROM 
    My_Table T1 
INNER JOIN Table_I_Am_Joining T2 ON 
    T1.code LIKE '%,' + CAST(T2.ref AS VARCHAR(20)) + ',%' OR 
    T1.code LIKE CAST(T2.ref AS VARCHAR(20)) + ',%' OR 
    T1.code LIKE '%,' + CAST(T2.ref AS VARCHAR(20)) OR 
    T1.code = CAST(T2.ref AS VARCHAR(20)) 

這依賴您的列中的代碼必須採用確切格式,逗號分隔且不得包含空格。如果情況並非如此,那麼這可能不會返回你想要得到的結果。

1

答案是規範化你的數據庫。

與此同時,在大型設備上執行更好的解決方法是使用臨時表。 (LIKE搜索不能使用索引)

該方法還顯示了標準化數據和處理空白的一些步驟。

如果您沒有,請先創建一個"Tally Table"這是一次性交易,Tally表格適用於allkindsthings

/*--- Create a Tally table. This only needs to be done once. 
    Note that "Master.dbo.SysColumns" is in all SQL 2000 installations. 
    For SQL 2005, or later, use "master.sys.all_columns". 
*/ 
SELECT TOP 11000 -- Adequate for most business purposes. 
    IDENTITY (INT, 1, 1) AS N 
INTO 
    dbo.Tally 
FROM 
    Master.dbo.SysColumns sc1, 
    Master.dbo.SysColumns sc2 

--- Add a Primary Key to maximize performance. 
ALTER TABLE  dbo.Tally 
ADD CONSTRAINT PK_Tally_N PRIMARY KEY CLUSTERED (N) WITH FILLFACTOR = 100 

現在假設你的表是:

CREATE TABLE ListO_Codes (ID INT IDENTITY(1,1), Code VARCHAR(88)) 

INSERT INTO ListO_Codes (Code) 
SELECT  '123,456,789,12'  UNION ALL 
SELECT  '456,073'    UNION ALL 
SELECT  '69,76,56' 


CREATE TABLE AnotherTable (ID INT IDENTITY(1,1), Ref VARCHAR(8), CodeWord VARCHAR (88)) 

INSERT INTO AnotherTable (Ref, CodeWord) 
SELECT  '12', 'Children'  UNION ALL 
SELECT  '123', 'of'   UNION ALL 
SELECT  '456', '-'    UNION ALL 
SELECT  '789', 'sun,'   UNION ALL 
SELECT  '073', 'see'   UNION ALL 
SELECT  '56', 'your'   UNION ALL 
SELECT  '69', 'time'   UNION ALL 
SELECT  '76', 'has' 

然後臨時表是:

CREATE TABLE #NORMALIZED_Data (LOD_id INT, Ref int) -- Make Ref varchar if it's not numeric 
INSERT INTO 
    #NORMALIZED_Data (LOD_id, Ref) 
SELECT 
    L.ID, 
    -- Split Code string using Tally table and Delimiters 
    LTrim (RTrim (SUBSTRING (',' + L.Code + ',', T.N+1, CHARINDEX (',', ',' + L.Code + ',', T.N+1) - T.N - 1))) 
FROM 
    dbo.Tally  T, 
    ListO_Codes  L 
WHERE 
    T.N < LEN (',' + L.Code + ',') 
AND 
    SUBSTRING (',' + L.Code + ',', T.N, 1) = ',' 


--- Index for performance 
CREATE CLUSTERED INDEX CL_NORMALIZED_Data_LOD_id_Ref 
ON #NORMALIZED_Data (LOD_id, Ref) WITH FILLFACTOR = 100 

然後搜索:

SELECT 
    L.ID, 
    L.Code, 
    A.Ref, 
    A.CodeWord 
FROM 
    #NORMALIZED_Data N 
INNER JOIN 
    ListO_Codes   L ON N.LOD_id = L.ID 
LEFT JOIN 
    AnotherTable  A ON N.Ref = A.Ref 
ORDER BY 
    L.ID, 
    A.Ref 

而結果是:

ID Code    Ref CodeWord 
-- -------------- --- -------- 
1  123,456,789,12 12  Children 
1  123,456,789,12 123 of 
1  123,456,789,12 456 - 
1  123,456,789,12 789 sun, 
2  456,073   073 see 
2  456,073   456 - 
3  69,76,56   56  your 
3  69,76,56   69  time 
3  69,76,56   76  has