我正试图在cd.result =' Pass'时对案件的时间进行过度调整。我不能把它放在where条件中,因为我需要其他列出现在所有条件下,而不仅仅是通过情境。我尝试在子选择中执行此操作,但似乎需要永远执行(35分钟和计数)。
select ctir.item_dbkey, item_id
,ctir.portion_id
,Round(avg(CAST(time_elapsed as float)/1000), 3) as Avg_Time_Sec
,SUM(CASE when cd.result = 'Pass' Then 1 Else 0 END) as N_PASS
,SUM(CASE when cd.result = 'Fail' Then 1 Else 0 END) as N_FAIL
,count(ctir.testassignment_ID)as N_Total
from candidate_testItem_response ctir
join [dbo].[Candidate_TestAssignment_Portion] ctil on ctir.TestAssignment_ID = ctil.TestAssignment_ID and ctir.portion_id = ctil.portion_ID
join item_bank ib on ctir.item_dbkey = ib.item_dbkey
join candidate_data cd on ctir.testassignment_id = cd.TestAssignment_ID and ctir.Portion_ID = cd.Portion_ID
where ctir.portion_id = 15780
and ctil.start_time >= '2017-01-01 00:00:00.000'
group by ctir.item_dbkey, ctir.Portion_ID, item_id
我的subselect尝试太慢了,可能不会最终工作:
select ctir.item_dbkey, item_id
,ctir.portion_id
,(select Round(avg(CAST(time_elapsed as float)/1000), 3) as Avg_Time_Sec
from candidate_testItem_response ctir
join candidate_data cd on ctir.testassignment_id = cd.TestAssignment_ID and ctir.Portion_ID = cd.Portion_ID
where cd.result = 'pass')
,SUM(CASE when cd.result = 'Pass' Then 1 Else 0 END) as N_PASS
,SUM(CASE when cd.result = 'Fail' Then 1 Else 0 END) as N_FAIL
,count(ctir.testassignment_ID) as N_Total
from candidate_testItem_response ctir
join [dbo].[Candidate_TestAssignment_Portion] ctil on ctir.TestAssignment_ID = ctil.TestAssignment_ID and ctir.portion_id = ctil.portion_ID
join item_bank ib on ctir.item_dbkey = ib.item_dbkey
join candidate_data cd on ctir.testassignment_id = cd.TestAssignment_ID and ctir.Portion_ID = cd.Portion_ID
where ctir.portion_id = 15780
and ctil.start_time >= '2017-01-01 00:00:00.000'
group by ctir.item_dbkey, ctir.Portion_ID, item_id
所以我的目标是为那些使用cd.result =' pass'的人添加一个平均avg_time_sec的列。我尝试了几个版本,但我很难过。
答案 0 :(得分:1)
CTE有帮助吗?
WITH TEMP
AS (
SELECT ctir.item_dbkey
,item_id
,ctir.portion_id
,ctir.testassignment_id
,SUM(CASE
WHEN cd.result = 'Pass'
THEN 1
ELSE 0
END) AS N_PASS
,SUM(CASE
WHEN cd.result = 'Fail'
THEN 1
ELSE 0
END) AS N_FAIL
,count(ctir.testassignment_ID) AS N_Total
FROM candidate_testItem_response ctir
JOIN [dbo].[Candidate_TestAssignment_Portion] ctil ON ctir.TestAssignment_ID = ctil.TestAssignment_ID
AND ctir.portion_id = ctil.portion_ID
JOIN item_bank ib ON ctir.item_dbkey = ib.item_dbkey
JOIN candidate_data cd ON ctir.testassignment_id = cd.TestAssignment_ID
AND ctir.Portion_ID = cd.Portion_ID
WHERE ctir.portion_id = 15780
AND ctil.start_time >= '2017-01-01 00:00:00.000'
GROUP BY ctir.item_dbkey
,ctir.Portion_ID
,item_id
)
SELECT t.item_dbkey
,t.item_id
,t.portion_id
,t.N_PASS
,t.N_FAIL
,t.N_TOTAL
,Round(avg(CAST(ctir.time_elapsed AS FLOAT) / 1000), 3) AS Avg_Time_Sec
FROM TEMP t
LEFT JOIN candidate_testItem_response ctir
JOIN candidate_data cd ON ctir.testassignment_id = t.TestAssignment_ID
AND ctir.Portion_ID = t.Portion_ID
WHERE cd.result = 'pass'
GROUP BY t.item_dbkey
,t.item_id
,t.portion_id
,t.N_PASS
,t.N_FAIL
,t.N_TOTAL
编辑:这样,您只能在一个非索引表(TEMP)上运行一次,而不是在子查询上运行很多次。
答案 1 :(得分:1)
让你试着像:
select ctir.item_dbkey, item_id, ctir.portion_id
,Round(avg(
CASE when cd.result = 'Pass'
THEN CAST(time_elapsed as float)/1000
ELSE null END), 3) as Avg_Time_Sec
,SUM(CASE when cd.result = 'Pass' Then 1 Else 0 END) as N_PASS
,SUM(CASE when cd.result = 'Fail' Then 1 Else 0 END) as N_FAIL
,count(ctir.testassignment_ID)as N_Total
from candidate_testItem_response ctir
join [dbo].[Candidate_TestAssignment_Portion] ctil on ctir.TestAssignment_ID = ctil.TestAssignment_ID and ctir.portion_id = ctil.portion_ID
join item_bank ib on ctir.item_dbkey = ib.item_dbkey
join candidate_data cd on ctir.testassignment_id = cd.TestAssignment_ID and ctir.Portion_ID = cd.Portion_ID
where ctir.portion_id = 15780
and ctil.start_time >= '2017-01-01 00:00:00.000'
group by ctir.item_dbkey, ctir.Portion_ID, item_id
答案 2 :(得分:1)
将条件平均值计算为条件和/条件计数
select ctir.item_dbkey, item_id
,ctir.portion_id
,Round(SUM(CASE when cd.result = 'Pass' THEN CAST(time_elapsed as float)/1000 END)/COUNT(CASE when cd.result = 'Pass' THEN 1 END), 3) as Avg_Time_Sec
,SUM(CASE when cd.result = 'Pass' Then 1 Else 0 END) as N_PASS
,SUM(CASE when cd.result = 'Fail' Then 1 Else 0 END) as N_FAIL
,count(ctir.testassignment_ID)as N_Total
from candidate_testItem_response ctir
join [dbo].[Candidate_TestAssignment_Portion] ctil on ctir.TestAssignment_ID = ctil.TestAssignment_ID and ctir.portion_id = ctil.portion_ID
join item_bank ib on ctir.item_dbkey = ib.item_dbkey
join candidate_data cd on ctir.testassignment_id = cd.TestAssignment_ID and ctir.Portion_ID = cd.Portion_ID
where ctir.portion_id = 15780
and ctil.start_time >= '2017-01-01 00:00:00.000'
group by ctir.item_dbkey, ctir.Portion_ID, item_id
答案 3 :(得分:1)
在这种情况下,您可以转离CASE语句并使用UNION然后聚合结果 - 它应该更快。
SELECT
item_dbkey,
item_id,
portion_id,
MAX(Avg_Time_Sec) AS Avg_Time_Sec,
SUM(n_pass) AS N_PASS,
SUM(n_fail) AS N_FAIL,
SUM(n_pass) + SUM(n_fail) AS N_Total
FROM
(
SELECT
ctir.item_dbkey,
item_id,
ctir.Portion_ID,
ROUND(AVG(CAST(time_elapsed AS FLOAT) / 1000), 3) as Avg_Time_Sec,
COUNT( 1 ) AS N_PASS,
0 AS N_FAIL
FROM
candidate_testItem_response AS ctir
join [dbo].[Candidate_TestAssignment_Portion] AS ctil
on ctir.TestAssignment_ID = ctil.TestAssignment_ID and ctir.portion_id = ctil.portion_ID
join item_bank AS ib
on ctir.item_dbkey = ib.item_dbkey
join candidate_data AS cd
on ctir.testassignment_id = cd.TestAssignment_ID and ctir.Portion_ID = cd.Portion_ID
WHERE
ctir.portion_id = 15780 AND
cd.result = 'Pass' AND
ctil.start_time >= '2017-01-01 00:00:00.000'
GROUP BY
ctir.item_dbkey,
item_id,
ctir.Portion_ID
UNION
SELECT
ctir.item_dbkey,
item_id,
ctir.Portion_ID,
0 AS Avg_Time_Sec,
0 AS N_PASS,
COUNT( 1 ) AS N_FAIL
FROM
candidate_testItem_response AS ctir
join [dbo].[Candidate_TestAssignment_Portion] AS ctil
on ctir.TestAssignment_ID = ctil.TestAssignment_ID and ctir.portion_id = ctil.portion_ID
join item_bank AS ib
on ctir.item_dbkey = ib.item_dbkey
join candidate_data AS cd
on ctir.testassignment_id = cd.TestAssignment_ID and ctir.Portion_ID = cd.Portion_ID
WHERE
ctir.portion_id = 15780 AND
cd.result = 'Fail' AND
ctil.start_time >= '2017-01-01 00:00:00.000'
GROUP BY
ctir.item_dbkey,
item_id,
ctir.Portion_ID
) AS inner_query
GROUP BY
item_dbkey,
item_id,
portion_id