Tsql T-SQL外部联接不起作用
我使用连接编写了一个查询,以显示使用部件序列号的摘要 显然,它不起作用 在此处使用直接搜索:Tsql T-SQL外部联接不起作用,tsql,self-join,Tsql,Self 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%
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%'
我得到以下示例输出:
注意,对于这个零件号,我需要两个测试的结果
现在转到我创建的不起作用的查询:
此第一个版本将返回一条记录:
我猜上面的查询会产生一个结果,因为有两个或多个记录可供比较。对吧?
我修改了上面的查询,希望返回最新的记录,但是这个版本没有返回任何内容:
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)))
有人能指出我如何让这个查询返回我想要的单个结果吗?我认为您想要每个零件的最新测试结果记录,对吗
如果您使用的是MSSQL 2005或更高版本,请查看MSDN文档,这将使其变得非常简单。好的,我已经找到了调整代码以产生所需结果的方法 首先,以下是我使用的数据:
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')
接下来,我创建了两个非常相似的查询。事实证明,我在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))
)
以下是我如何提取第一个测试结果和日期:
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))
)
我希望其他人觉得这很有用
~Joe正如@Will A所问的,你的目标是什么?要获取每个零件的最新测试结果?无法查看。这项工作使用的是Microsoft ISA代理服务器,我们的网络管理员不知道如何让它通过MSDN页面。他们总是超时。老鼠。我们还坚持使用SQL Server 2000 Enterprise。@jp2code-您的工作块msdn?那真是一份多么糟糕的工作啊。当然,老板,如果我能使用msdn文档的话,我可以让它工作,这本应该是上周完成的。现在我必须回家看看msdn才能完成任务@JonH-work不会主动阻止MSDN,但我们的网络管理员看不到让我们的Microsoft ISA代理服务器通过站点的方法-尤其是如果我使用我的MSDN帐户登录。Msg 195,级别15,状态10:“row_number”不是可识别的函数名。首先,我坚持使用SQLServer2000企业版。第二,你的暗示仍然没有告诉我如何解决我的问题。我的逻辑似乎在那里。然而,我不知道使用您的行号会有什么帮助-即使我可以使用它。
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))
)