Sql 无法完成查询(运行时间太长)
我试图得到一些测试结果的总体通过率 序列号代表一种仪器。一台仪器要通过107项不同的测试。试验分为两部分:Sql 无法完成查询(运行时间太长),sql,sql-server,Sql,Sql Server,我试图得到一些测试结果的总体通过率 序列号代表一种仪器。一台仪器要通过107项不同的测试。试验分为两部分: Linux测试(21) 其他(共86个,如电压测试、灯光测试) 在两种情况下,仪器将被视为通行证 标准方式:它在一次运行中通过107个不同的测试。代码如下: 选择序列号 从桌子上 按序号、条目分组 有计数(不同的测试标准)>=107 另一种方法:它在一次运行中通过107个不同的测试,或者 它在一轮中通过了86项其他测试,在一轮中通过了21项Linux测试 晚些时候 表中的“overallt
+----------------+------------+---------------+------------+
| 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;
下面是一个工作示例,
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;
你能编辑你的问题并提供一些(简化的)样本数据和期望的结果吗?你也能在没有所有差异的情况下尝试吗?
光标
可能对问题没有帮助。看起来可以用数据集方法编写。while循环中没有fetch next。看起来像是一个无限循环问题。循环所能做的就是减慢一个本来很快的过程。在你的情况下,无限期。这应该是一个基于集合的update语句,带有大小写表达式。非常感谢。我是SQL新手,这可能需要一段时间才能理解和应用。无论如何,我真的很感谢你的帮助。np,一旦你评估了它,如果它对你有帮助,请选择它作为答案。如果您对代码或如何进行更改有任何疑问,请发布,如果我没有回复,我相信会有人回复;我会努力跟进的,我很乐意,但我不能,因为我的声誉低于15。
SN Entry_ Other Linux
170119904 1 4 NULL
180117000 1 3 1
170119904 2 5 1
180117000 2 1 NULL