2010-07-16 81 views
0

我有一個查詢,我使用連接編寫來顯示使用部件的Serial_Number的摘要。T-SQL外部連接不起作用

很明顯,它不工作!

使用這裏的直接搜索:

select Serial_Number, Op_ID, Date_Time as 'DecayDate', 
    DECAY.System_ID AS 'DecayID', Test_Result as 'DecayResult' 
from Test_Results 
where serial_number='CP21295 1006 09' and system_id like '%decay%' 

我得到這個樣本輸出:

Serial_Number  Op_ID DecayDate    DecayID  DecayResult 
CP21295 1006 09 003468 2009-10-15 06:36:13.643 AA_DECAY_6 FAILED 
CP21295 1006 09 003468 2009-10-05 08:08:38.503 AA_DECAY_6 PASSED 

注意有兩個(2)試驗,我需要這一個部件號的結果。

我們我創建的查詢不起作用:


這第一個版本將返回ONE記錄:

SELECT LABEL.Serial_Number, 
    DECAY.Op_ID, 
    DECAY.Date_Time AS 'DecayDate', 
    DECAY.System_ID AS 'DecayID', 
    CASE 
    WHEN DECAY.Test_Result LIKE '%fail%' THEN 'FAIL' 
    WHEN DECAY.Test_Result LIKE '%pass%' THEN 'PASS' 
    ELSE NULL 
    END AS 'DecayResult' 
    FROM 
    ACP_Parts AS LABEL 
    LEFT OUTER JOIN (
    SELECT I.Serial_Number, I.Op_ID, I.Date_Time, I.System_ID, I.Test_Result 
     FROM Test_Results I 
    LEFT OUTER JOIN Test_Results O ON (
     I.Serial_Number=O.Serial_Number) AND 
     (O.Date_Time<I.Date_Time) -- AND (O.Serial_Number IS NULL) // didn't work 
    WHERE 
     (I.Test_Result LIKE '%pass%' OR I.Test_Result LIKE '%fail%') AND 
     (I.System_ID like '%decay%') AND 
     (O.Test_Result LIKE '%pass%' OR O.Test_Result LIKE '%fail%') AND 
     (O.System_ID like '%decay%') 
    ) AS DECAY ON 
     (LABEL.Serial_Number=DECAY.Serial_Number) AND 
     (LABEL.Date_Time<DECAY.Date_Time) 
    WHERE 
    (LABEL.Serial_Number IN (
     SELECT DISTINCT Serial_Number 
     FROM ACP_Parts 
     WHERE (Serial_Number IS NOT NULL) AND 
     (DATEADD(yy, - 1, GETDATE()) < Date_Time))) 

輸出

Serial_Number  DecayOp DecayDate    DecayID    DecayResult 
CP21295 1006 09 003468 2009-10-15 06:36:13.643 AA_DECAY_6   PASS 

我猜測上面的查詢會產生一個結果,因爲有兩個或更多的記錄要比較。對?


我修改了上面的查詢,希望能返回最新的紀錄,但是這個版本不返回任何東西:

SELECT LABEL.Serial_Number, 
    DECAY.Op_ID, 
    DECAY.Date_Time AS 'DecayDate', 
    DECAY.System_ID 'DecayID', 
    CASE 
    WHEN DECAY.Test_Result LIKE '%fail%' THEN 'FAIL' 
    WHEN DECAY.Test_Result LIKE '%pass%' THEN 'PASS' 
    ELSE NULL 
    END AS 'DecayResult' 
    FROM 
    ACP_Parts AS LABEL 
    LEFT OUTER JOIN (
    SELECT TOP 1 Serial_Number, Op_ID, Date_Time, System_ID, Test_Result 
    FROM Test_Results 
    WHERE 
     (System_ID like '%decay%') AND 
     (Test_Result LIKE '%pass%' OR Test_Result LIKE '%fail%') 
    ORDER BY Date_Time DESC 
    ) AS DECAY ON 
     (LABEL.Serial_Number=DECAY.Serial_Number) AND 
     (LABEL.Date_Time<DECAY.Date_Time) 
    WHERE 
    (LABEL.Serial_Number IN (
     SELECT DISTINCT Serial_Number 
     FROM ACP_Parts 
     WHERE (Serial_Number IS NOT NULL) AND 
     (DATEADD(yy, - 1, GETDATE()) < Date_Time))) 

輸出

Serial_Number  DecayOp DecayDate    DecayID    DecayResult 
CP21295 1006 09 NULL NULL     NULL     NULL 

莫非有人指出我如何才能使這個查詢返回罪結果我後?

+0

正如@ Will A所問,你的目標是什麼?要獲得(每個)部分的最新測試結果? – 2010-07-16 21:28:20

+0

是........... – jp2code 2010-07-16 21:31:51

回答

0

OK,我已經找到方法來調整代碼產生我想要的結果。

首先,這裏是我使用的數據:

CREATE TABLE JP1 (Serial_Number VarChar(20), Date_Time DateTime, Test_Result VarChar(255)) 
INSERT JP1 VALUES ('T900 09', '2009-10-10 01:15:00.000', 'NO TEST, Failed to Dump') 
INSERT JP1 VALUES ('T901 09', '2009-10-10 01:20:00.000', '(BLUE) PASS (WHITE) FAIL') 

CREATE TABLE JP2 (Serial_Number VarChar(20), Date_Time DateTime, Test_Result VarChar(255)) 
INSERT JP2 VALUES ('T900 09', '2009-10-15 01:15:00.000', 'NO TEST, Failed to Dump') 
INSERT JP2 VALUES ('T900 09', '2009-10-15 02:15:00.000', '(BLUE) PASS (WHITE) FAIL') 
INSERT JP2 VALUES ('T900 09', '2009-10-15 04:25:00.000', 'TEST ABORTED') 
INSERT JP2 VALUES ('T900 09', '2009-10-15 04:59:00.000', '(BLUE) FAIL (WHITE) FAIL') 
INSERT JP2 VALUES ('T900 09', '2009-10-15 05:09:00.000', '(WHITE) NO TEST') 
INSERT JP2 VALUES ('T900 09', '2009-10-15 05:34:00.000', 'B=Pass.,W=FAIL, Final Fill') 
INSERT JP2 VALUES ('T900 09', '2009-10-15 06:06:00.000', 'PASSED PD') 
INSERT JP2 VALUES ('T900 09', '2009-10-15 06:30:00.000', 'TEST ABORTED') 
INSERT JP2 VALUES ('T900 09', '2009-10-15 06:36:00.000', 'PASS') 
INSERT JP2 VALUES ('T900 09', '2009-10-15 06:50:00.000', 'FAIL') 
INSERT JP2 VALUES ('T900 09', '2009-10-05 08:08:00.000', 'NO TEST, Operator cancel') 

接下來,我創建了兩個(2)非常類似的查詢。事實證明,我在LEFT OUTER JOIN條款中提出的要求需要在WHERE條款中模擬。

這裏是我提取FIRST PASS結果和日期:

SELECT LABEL.Serial_Number, 
    DECAY.Date_Time AS 'DecayDate', 
    CASE 
    WHEN DECAY.Test_Result LIKE '%fail%' THEN 'FAIL' 
    WHEN DECAY.Test_Result LIKE '%pass%' THEN 'PASS' 
    ELSE NULL 
    END AS 'DecayResult' 
FROM JP1 AS LABEL 
LEFT OUTER JOIN (
    SELECT I.Serial_Number, I.Date_Time, I.Test_Result 
    FROM 
     JP2 AS I 
     LEFT OUTER JOIN JP2 AS O 
     ON 
     (I.Serial_Number=O.Serial_Number) AND 
     ((O.Test_Result LIKE '%pass%') OR (O.Test_Result LIKE '%fail%')) AND -- //Gets First Test! 
     (O.Test_Result NOT LIKE '%NO TEST%') AND 
     (O.Date_Time<I.Date_Time) -- //(selects FIRST pass or fail) 
     -- (I.Date_Time<O.Date_Time) -- //(selects LAST pass or fail) 
    WHERE 
     (I.Test_Result LIKE '%pass%' OR I.Test_Result LIKE '%fail%') AND -- //Gets First Test! 
     (I.Test_Result NOT LIKE '%NO TEST%') AND 
     (O.Serial_Number IS NULL) 
) AS DECAY ON 
(LABEL.Serial_Number=DECAY.Serial_Number) AND 
(LABEL.Date_Time<DECAY.Date_Time) 
WHERE 
(LABEL.Serial_Number IN (
    SELECT DISTINCT Serial_Number 
    FROM JP1 
    WHERE (Serial_Number IS NOT NULL) AND 
    (DATEADD(yy, - 1, GETDATE()) < Date_Time)) 
) 

這裏是我提取FIRST測試結果和日期:

SELECT LABEL.Serial_Number, 
    DECAY.Date_Time AS 'DecayDate', 
    CASE 
    WHEN DECAY.Test_Result LIKE '%fail%' THEN 'FAIL' 
    WHEN DECAY.Test_Result LIKE '%pass%' THEN 'PASS' 
    ELSE NULL 
    END AS 'DecayResult' 
FROM JP1 AS LABEL 
LEFT OUTER JOIN (
    SELECT I.Serial_Number, I.Date_Time, I.Test_Result 
    FROM 
     JP2 AS I 
     LEFT OUTER JOIN JP2 AS O 
     ON 
     (I.Serial_Number=O.Serial_Number) AND 
     ((O.Test_Result LIKE '%pass%') AND (O.Test_Result NOT LIKE '%fail%')) AND -- //Gets First Pass! 
     (O.Test_Result NOT LIKE '%NO TEST%') AND 
     (O.Date_Time<I.Date_Time) -- //(selects FIRST pass or fail) 
     -- (I.Date_Time<O.Date_Time) -- //(selects LAST pass or fail) 
    WHERE 
     (I.Test_Result LIKE '%pass%' AND I.Test_Result NOT LIKE '%fail%') AND -- //Gets First Pass! 
     (I.Test_Result NOT LIKE '%NO TEST%') AND 
     (O.Serial_Number IS NULL) 
) AS DECAY ON 
(LABEL.Serial_Number=DECAY.Serial_Number) AND 
(LABEL.Date_Time<DECAY.Date_Time) 
WHERE 
(LABEL.Serial_Number IN (
    SELECT DISTINCT Serial_Number 
    FROM JP1 
    WHERE (Serial_Number IS NOT NULL) AND 
    (DATEADD(yy, - 1, GETDATE()) < Date_Time)) 
) 

我希望別人找這有用!

〜Joe

0

我是正確的思維,你要爲每個部分的最新test_result記錄?

退房ROW_NUMBER() OVER (PARTITION BY... ORDER BY ...)在MSDN文檔 - 這將使它令人眼花繚亂的簡單 - 假設你使用MSSQL 2005或以上。

+1

看不到它。工作使用Microsoft ISA代理服務器,我們的網絡管理員無法弄清楚如何讓它通過MSDN頁面。他們總是超時。 – jp2code 2010-07-16 21:31:06

+0

大鼠。我們也堅持使用SQL Server 2000 Enterprise。 – jp2code 2010-07-16 21:32:35

+1

@ jp2code - 你的工作塊msdn?真的可能有多糟糕的工作。 「如果我能夠使用上週完成的msdn文檔,我肯定可以讓它工作,現在我必須回家看看msdn才能完成工作!」 – JonH 2010-07-16 21:54:52