无法完成我的查询(运行时间太长)

时间:2018-04-02 15:19:18

标签: sql sql-server

我试图获得某些测试结果的总体通过率。

序列号代表仪器。有一种仪器可以通过107种不同的测试。测试分为两部分:

  1. Linux测试(21)
  2. 其他(总共86个,如电压测试,光测试)。
  3. 一种文书将被视为两种方式的传递。

    1. 标准方式:它在一次运行中通过107次不同的测试。代码如下:

      SELECt序列号 从表 GROUP BY序列号,条目 具有计数(DISTINCT testcriteria)> = 107

    2. 替代方式:它在一次运行中通过107次不同的测试 它在一轮中通过86次其他测试,并通过21次Linux测试 后来回合。

      表中的“overalltestrunstatus”列仅表示仪器通过列表中的所有测试,但列表本身可能不完整。 (假设一个乐器得到“整体调整状态”,但是它通过的测试是<107,它仍然是失败的)。有时,如果仪器失败或通过小于一定数量的测试,仪器将重新运行。因此,“输入”代表该仪器运行的回合。

    3. 我的目标是找到那些通过测试但不是以标准方式通过的仪器。

      我的想法是找到所有那些具有“overalltestrunstatus”等于通过但通过小于107的测试的乐器。然后迭代结果和乐器的每个条目。如果它通过了86个其他测试,我会给它一个检查,如果通过其他21个Linux,我会给它另一个检查。稍后我会计算所有那些有两张支票的乐器。

      我想要的是:

      +----------------+------------+---------------+------------+
      |  serial number |   entries  | others tests  | Linux tests|
      +----------------+------------+---------------+------------+
      |  170119904     |     1      |       yes     |    no      |
      +----------------+------------+---------------+------------+
      |  170119904     |     2      |       no      |    yes     |
      +----------------+------------+---------------+------------+
      |  180117000     |     1      |       no      |    no      |
      +----------------+------------+---------------+------------+
      |  180117000     |     2      |       no      |    no      |
      +----------------+------------+---------------+------------+
      

      通过检查特定序列号是否已通过其他测试和Linux测试。我能够知道它的通过与否。

      我的问题是,每次查询运行20个小时,然后发出错误,如“已断开连接”或“发生某些内部错误”。我永远无法真正理解它。有什么想法吗?我非常感谢你的帮助。

      这是表格:

      +----------------------+--------------+----------+----------------+------------+---------+
      | overalltestrunstatus | serialnumber | passfail |  testcriteria  |  testname  | Entries |
      +----------------------+--------------+----------+----------------+------------+---------+
      | PASS                 |    170119904 | Pass     | Backlight test | Functional |       1 |
      +----------------------+--------------+----------+----------------+------------+---------++----------------------+--------------+----------+----------------+------------+---------+
      | PASS                 |    170119904 | Pass     | Linux set test | Functional |       1 |
      +----------------------+--------------+----------+----------------+------------+---------++----------------------+--------------+----------+----------------+------------+---------+
      | PASS                 |    170119904 | Pass     | Factor    test | Functional |       1 |
      +----------------------+--------------+----------+----------------+------------+---------++----------------------+--------------+----------+----------------+------------+---------+
      | PASS                 |    170119904 | Pass     | Voltage   test | Functional |       1 |
      +----------------------+--------------+----------+----------------+------------+---------++----------------------+--------------+----------+----------------+------------+---------+
      | PASS                 |    170119904 | Pass     | Digital   test | Functional |       1 |
      +----------------------+--------------+----------+----------------+------------+---------++----------------------+--------------+----------+----------------+------------+---------+
      | PASS                 |    170119904 | Pass     | Detactor  test | Functional |       1 |
      +----------------------+--------------+----------+----------------+------------+---------+
      

      这是我的代码:

      /* -serialnumber |-- entries--|--Pass1 --|--Pass2---|
         --------------|------------|----------|----------|
      */
      DECLARE @checklist TABLE
      (
        serialnumber varchar(100), 
        entries int,
        passother int default  0,
        passlinux int default  0
      )
      
      DECLARE @temp TABLE
      (
        serialnumber int, 
        entries int,
        passother int default  0,
        passlinux int default  0
      )
      
      -- select serial number into the table
      
      -- PCBA 214 ge to be counted
      INSERT INTO @checklist (serialnumber, entries)
          SELECT serialnumber, entries 
          FROM dbo.boardtestresults1_full_view  t2
          WHERE partnumber = 'PCBA-10214-0001' 
              AND t2.serialnumber IN 
              (SELECT DISTINCT serialnumber
              FROM dbo.boardtestresults1_full_view  
              WHERE partnumber = 'PCBA-10214-0001' AND overalltestrunstatus = 'Pass' AND serialnumber NOT IN (
              SELECT DISTINCT serialnumber
              FROM dbo.boardtestresults1_full_view  
              WHERE partnumber = 'PCBA-10214-0001' AND overalltestrunstatus = 'Pass'
              GROUP BY serialnumber, Entries 
              HAVING COUNT(DISTINCT combined) >= 107))
      
      
      
      -- check all for PCBA 10214
      
      DECLARE @MyCursor1 CURSOR;
      DECLARE @snumber VARCHAR(100); -- serailnumber
      DECLARE @entries VARCHAR(100); -- entries
      DECLARE @others int;
      DECLARE @linux int;
      DECLARE @pass1 int;
      DECLARE @pass2 int;
      
      BEGIN
          -- get serial numbers for all PCBA 214 from checklist
          SET @MyCursor1 = CURSOR FOR
          SELECT serialnumber, Entries
          FROM @checklist
          WHERE serialnumber like 'PCBA-10214-0001%' 
      
          -- get the roll
          OPEN @MyCursor1 
          FETCH NEXT FROM @MyCursor1 
          INTO @snumber, @entries
      
          -- loop through
          WHILE @@FETCH_STATUS = 0
          BEGIN
            /*
               YOUR ALGORITHM GOES HERE   
            */
          -- if pass the most or if pass linux
          IF ((SELECT COUNT(DISTINCT combined)FROM dbo.boardtestresults1_full_view WHERE  serialnumber = @snumber AND entries = @entries) >= 86)
              UPDATE @checklist SET passother = 1 WHERE serialnumber = @snumber AND entries = @entries
          ELSE IF ((SELECT COUNT(DISTINCT combined)FROM dbo.boardtestresults1_full_view WHERE  serialnumber = @snumber AND entries = @entries AND testname = 'LINUX Test' AND overalltestrunstatus = 'Pass') >= 21) 
              UPDATE @checklist SET passlinux = 1 WHERE serialnumber = @snumber AND entries = @entries
          END; 
      
          CLOSE @MyCursor1 ; 
          DEALLOCATE @MyCursor1;
      END;
      

1 个答案:

答案 0 :(得分:1)

这是一个工作示例,PassFail列未被评估,而它在那里它没有查询的限制。我添加了一个名为TestType的列来简化示例,在您的用例中不太清楚Linux测试是如何从样本集派生的,也许是TestCriteria,但这使得它不那么模糊。您应该能够获得测试的二进制文件,如果您需要进一步的帮助,您需要定义所有数据,我们可以提供帮助。

declare @example as table (
    ExampleID     int identity(1,1) not null primary key clustered
,   OverAllStatus nvarchar(255) not null
,   SN            int not null
,   PassFail      nvarchar(255) not null
,   TestType      bit not null
,   TestCriteria  nvarchar(255) not null
,   Entry_        int not null
);

insert into @example (OverAllStatus, SN, PassFail, TestType, TestCriteria, Entry_)
select 'PASS', 170119904, 'Pass', 0, 'Backlight test', 1 union all
select 'PASS', 170119904, 'Pass', 0, 'Factor test', 1 union all
select 'PASS', 170119904, 'Pass', 0, 'Voltage test', 1 union all
select 'PASS', 170119904, 'Pass', 0, 'Detactor test', 1 union all

select 'PASS', 170119904, 'Pass', 0, 'Backlight test', 2 union all
select 'PASS', 170119904, 'Pass', 1, 'Linux set test', 2 union all
select 'PASS', 170119904, 'Pass', 0, 'Factor test', 2 union all
select 'PASS', 170119904, 'Pass', 0, 'Voltage test', 2 union all
select 'PASS', 170119904, 'Fail', 0, 'Digital test', 2 union all
select 'PASS', 170119904, 'Pass', 0, 'Detactor test', 2 union all

select 'PASS', 180117000, 'Pass', 0, 'Backlight test', 1 union all
select 'PASS', 180117000, 'Pass', 1, 'Linux set test', 1 union all
select 'PASS', 180117000, 'Pass', 0, 'Factor test', 1 union all
select 'PASS', 180117000, 'Pass', 0, 'Digital test', 2 union all
select 'PASS', 180117000, 'Pass', 0, 'Detactor test', 1;


  --| Control Group, only those that pass but does not have 107 records (OverAllStatus)
  ;with cte as (
     select SN
          , Entry_
          , count(*) cnt
       from @example
      where OverAllStatus = 'Pass'
   group by SN, Entry_
   --| Control count - this is your 107 or the numbers of tests the SN has passed
     having count(*) < 7
            )
   --| We are setting the count of records to the Test Type or the grouping
    , cte2 as (
    select b.SN
         , a.Entry_
         , iif(TestType = 1, 'Linux', 'Other') Test
      from cte a
      join @example b
        on a.SN = b.SN
       and a.Entry_ = b.Entry_
            )
    --| Roll up the counts
    , cte3 as ( 
    select distinct a.SN
         , a.Entry_
         , count(*) over(partition by a.SN, a.Test, a.Entry_) cnt
         , a.Test
      from cte2 a
            )

  --| Pivot the result set
    select SN
         , Entry_
         , [Other]
         , [Linux]
      from (
                select SN
                     , Entry_
                     , cnt
                     , test
                  from cte3
                  ) as x
            pivot 
                (
                 max(cnt)
                 for Test in ([Other], [Linux])
                ) as p;
  

结果集:

SN          Entry_  Other   Linux
170119904   1       4       NULL
180117000   1       3       1
170119904   2       5       1
180117000   2       1       NULL