创建T-SQL摘要行

时间:2010-07-14 16:42:55

标签: sql sql-server tsql

我的表中的数据类似于以下示例数据:

 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.

我需要创建一些脚本遍历给定Serial_Number的所有记录,并确定它是通过还是失败。每个部分通常有多个条目。

一项测试需要确定零件的状态,或者最后一次测试结果是PASS还是FAIL,忽略“TEST ABORTED”或“Chamber Calibration Factor Too High”等数据。

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

我觉得我需要创建一些选择不同序列号的东西,然后编写一个迭代数据的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 (Serial_Number=@serialNum) 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 个答案:

答案 0 :(得分: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%')

如果两个通过/未通过的结果具有相同的date_time值,则此解决方案可能会出现问题。除非你决定如何处理,否则这可能是任何解决方案的问题。