2010-07-14 125 views
0

我有,看起来像下面的示例数据表中的数据:创建T-SQL摘要行

varchar(20) | DateTime    | varchar(20) |varchar(255) 
_Serial_Number__|_Date_Time______________|_System_ID___|_Test_Result________________ 
C035993 0703 05 |2005-08-18 13:43:33.717 |VTI-Chamber1 | (BLUE) TEST ABORTED, LEAKFP SPUN DOWN 
C035993 0702 05 |2005-08-18 13:51:52.640 |VTI-Chamber1 | FAIL: Squirt Test. 
C035993 0704 05 |2005-08-18 14:18:13.607 |VTI-Chamber1 | TEST ABORTED 
C035993 0705 05 |2005-08-18 14:30:43.717 |VTI-Chamber1 | B=FAIL, Final N2 Fill after Settle, W=PASS, 
C035993 0707 05 |2005-08-18 14:41:59.310 |VTI-Chamber1 | FAIL: Fine Test. 
C035878 0775 05 |2005-08-18 15:38:25.810 |VTI-Chamber1 | Chamber Calibration Factor Too High 
C035878 0774 05 |2005-08-18 15:43:23.000 |VTI-Chamber1 | FAIL Pressure Decay Test 
C035993 0674 05 |2005-08-18 15:51:49.467 |VTI-Chamber1 | FAIL: Squirt Test. 
BLANKTEST  |2005-08-18 15:58:40.793 |VTI-Chamber3 | Pass. 
C035993 0706 05 |2005-08-18 15:59:03.200 |VTI-Chamber1 | Pass. 

我需要创建几个脚本通过所有的记录对于给定的序列号,并确定如果它通过或失败。每个零件通常有多个条目。

一个测试需要确定部件的状态,或者最后一个测试结果是PASS还是FAIL,忽略诸如'TEST ABORTED'或'Chamber Calibration Factor Too High'之类的数据。

第二个测试需要确定零件的质量,我们使用的标准是检查零件是否在第一个测试中通过,再次忽略错误的数据,如'TEST ABORTED'或'Chamber校准因子太高“。

我觉得我需要创建一些选择不同序列号的东西,然后编写一个迭代数据的while循环。

我有一些工作,但我目前没有办法让我返回的数据按Date_Time字段排序。

如果我能弄清那部分,我应该设置。

有人可以告诉我,我可以做些什么来允许我的脚本过滤Date_Time字段?

declare @result varChar(10), @serialNum varChar(20), @testResult varChar(255) 
declare snList cursor for 
    select distinct TR.Serial_Number 
    from Test_Results TR 
    left join ACP_Parts AP on (TR.Serial_Number=AP.Serial_Number) 
    where (AP.Serial_Number is not null) 
open snList 
fetch next from snList into @serialNum 
while (@@fetch_status=0) begin 
    set @result='' 
    declare resultList Cursor for 
     select Test_Result 
     from Test_Results 
     where ([email protected]) and (System_ID Like '%Chamb%') 
    open resultList 
    fetch next from resultList into @testResult 
    while (@@fetch_status=0) and (@result<>'PASS') begin 
     set @result=case 
      when (0<CharIndex('fail', @testResult)) then 'FAIL' 
      when (0<CharIndex('pass', @testResult)) then 'PASS' 
      else '' 
     end 
    end 
    close resultList 
    select @serialNum as 'Serial_Number', @result as 'Test_Result' 
    fetch next from snList into @serialNum 
end 
close snList 

文件结束。

+1

向我们展示样品输出请... – gbn 2010-07-14 16:43:29

+2

YIKES!游标.......甚至没有定义为FAST_FORWARD ...... – 2010-07-14 16:47:00

+1

你也没有命令你的内部游标,这意味着如果有两个结果,那么输出是未定义的 - 它可能是通过或它可能会失败。确认!我也注意到,如果有一个结果是你不关心的,它可以将结果设置为“'而不管订购。 – 2010-07-14 17:15:15

回答

2

这是我最好的猜测,你想要做什么。除了使用与此类似的查询之外,我的下一个建议是聘请知道SQL并具有编程经验或者自己熟练掌握的人。

SELECT 
    TR1.serial_number, 
    CASE 
     WHEN TR1.test_result LIKE '%pass%' THEN 'Pass' 
     WHEN TR1.test_result LIKE '%fail%' THEN 'Fail' 
     ELSE NULL 
    END AS final_result 
FROM 
    Test_Results TR1 
LEFT OUTER JOIN Test_Results TR2 ON 
    TR2.serial_number = TR1.serial_number AND 
    (
     TR2.test_result LIKE '%pass%' OR 
     TR2.test_result LIKE '%fail%' 
    ) AND 
    TR2.test_date > TR1.test_date 
WHERE 
    (
     TR1.test_result LIKE '%pass%' OR 
     TR1.test_result LIKE '%fail%' 
    ) AND 
    TR2.serial_number IS NULL 

没有游标和单个语句。 LEFT OUTER JOIN基本上是查看是否有相同序列号的后续行通过或失败。如果没有,TR2.serial_number将为NULL,并且TR1行将因此成为通过或失败的最新测试结果。

如果你可以进一步限制通过/失败标准,那么这将是一个好主意,这样你就不会意外地使用错误的结果(例如,LIKE'pass%'会比LIKE'%pass%'更好)。

如果以相同的确切日期时间值通过两次合格/不合格结果,此解决方案可能会有问题。尽管除非您决定如何处理这个问题,否则这可能会成为任何解决方案的问题。

+0

Date_Time参数被记录到千分之一秒,是员工必须运行的手动测试。在我们所有的记录中,我认为我们没有一个人拿出重复的时间戳。 虽然我很好奇,知道这是如何工作的。特别是最后一行:'TR2.serial_number IS NULL'这是如何拉*任何*记录? – jp2code 2010-07-14 18:21:12

+0

由于TR2是通过左外连接的,所以该表被视为别名。当创建左外连接时,如果在连接表中找不到匹配项,则其所有列都将返回为NULL。假设serial_number是一个NOT NULL列,那么TR2.serial_number可能为NULL的唯一方法是在没有找到匹配的情况下 - 意味着不存在具有相同序列号的行,通过或失败结果,并且在晚于TR1的时间。如果是这种情况,则TR1必须是该序列号的最新通过/失败行。 – 2010-07-14 18:59:42

+0

本示例使用最新的Date_Time值确定结果。 我该如何修改它以给出第一个PASS或第一个FAIL,但跳过其他? – jp2code 2010-07-14 19:17:40