代码之家  ›  专栏  ›  技术社区  ›  jp2code

T-SQL外部联接不工作

  •  0
  • jp2code  · 技术社区  · 16 年前

    我有一个使用join编写的查询,它使用部件的序列号显示摘要。

    显然,它不起作用!

    使用此处的直接搜索:

    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)个测试需要结果。

    现在到我创建的不起作用的查询:


    第一个版本将返回 一 记录:

    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
    

    有人能指出我怎样才能让这个查询返回我想要的单一结果吗?

    2 回复  |  直到 16 年前
        1
  •  0
  •   Will A    16 年前

    我认为你想要每个部件的最新测试结果记录是对的吗?

    退房 ROW_NUMBER() OVER (PARTITION BY... ORDER BY ...) 在msdn文档中,假设您使用的是mssql 2005或更高版本,这将使它变得非常简单。

        2
  •  0
  •   jp2code    16 年前

    好的,我已经找到了调整代码以产生我想要的结果的方法。

    首先,我使用的数据如下:

    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 条款。

    以下是我如何提取 第一 通过结果和日期:

    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))
    )
    

    以下是我如何提取 第一 试验结果和日期:

    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))
    )
    

    我希望其他人觉得这有用!

    乔

    推荐文章