这些查询的区别

时间:2009-11-27 14:56:56

标签: sql sql-server-2008

我在MSSQL中以不同的方式执行查询,但第二个查询没有给出结果作为第一个查询。

Query 1:
    select dbresultsid, TestCase, BuildID, Analyzed,
         Verdict, 
         (select count(Verdict) from results where BuildID = 'Beta1' 
                 and Verdict = 'PASS') AS PASS, 
         (select count(Verdict) from results where BuildID = 'Beta1' 
                 and Verdict = 'FAIL') AS FAIL, 
         (select count(Verdict) from results where BuildID = 'Beta1' 
                 and Verdict = 'INCONC') AS INCONC, 
         (select count(Verdict) from results where BuildID = 'Beta1' 
                 and Verdict = 'TIMEOUT') AS TIMEOUT 
    from results 
    where BuildID = 'Beta1'       
    group by TestCase,dbresultsid 
    order by Analyzed

Query 2:

select dbresultsid, TestCase, BuildID, Analyzed,
         Verdict, 
(case when Verdict='PASS' then count(Verdict) else 0 end) as PASS,
(case when Verdict='FAIL' then count(Verdict) else 0 end) as FAIL,
(case when Verdict='INCONC' then count(Verdict) else 0 end) as INCONC,
(case when Verdict='TIMEOUT' then count(Verdict) else 0 end) as TIMEOUT
from results
where 
BuildID = 'Beta1'
group by TestCase,dbresultsid 
order by Analyzed


Results :
for Query 1:
if the total number of PASS = 20,
 then PASS column will display 20 everywhere.

Results :
for Query 2:
here whereever there is PASS, it displays 1 and the total 20 rows where pass is displayed there is 1, 

我希望查询2的结果与查询1的结果相同

请问任何想法?

感谢,

3 个答案:

答案 0 :(得分:0)

第一个查询使用WHERE执行SELECT,只返回具有匹配判定的行,然后计算这些行。第二个查询每次都计算所有行。

您可以尝试:

select 
  dbresultsid, TestCase, BuildID, Analyzed, Verdict, 
  Sum(case when Verdict='PASS' then 1 else 0 end) as PASS,
  Sum(case when Verdict='FAIL' then 1 else 0 end) as FAIL,
  Sum(case when Verdict='INCONC' then 1 else 0 end) as INCONC,
  Sum(case when Verdict='TIMEOUT' then 1 else 0 end) as TIMEOUT
from 
  results
where 
  BuildID = 'Beta1'
group by 
  TestCase, dbresultsid 
order by 
  Analyzed

测试数据:

  CREATE TABLE #Test (BuildID Integer, Verdict char(7))
  INSERT INTO #TEST (Buildid, Verdict)
    VALUES (1, 'PASS')
  INSERT INTO #TEST (Buildid, Verdict)
    VALUES (1, 'PASS')
  INSERT INTO #TEST (BuildID, Verdict)
    VALUES (2, 'FAIL')
  INSERT INTO #TEST (BuildID, Verdict)
    VALUES (3, 'INCONC')
  INSERT INTO #TEST (BuildID, Verdict)
    VALUES(4, 'TIMEOUT')

查询:

select buildid,
  sum(case verdict when 'PASS' then 1 else 0 end) as Pass,
  sum(case verdict when 'FAIL' then 1 else 0 end) as Fail,
  sum(case verdict when 'INCONC' then 1 else 0 end) as Inconc,
  sum(case verdict when 'TIMEOUT' then 1 else 0 end) as TimeOut
FROM #temp
group by buildid

输出:

Item    buildid PASS    Fail    Inconc  TimeOut 
1         1      2       0        0        0
2         2      0       1        0        0
3         3      0       0        1        0
4         4      0       0        0        1

答案 1 :(得分:0)

为什么不使用第一个?,在我看来,如果参考和分组的关键字定义得很好,我会认为这是一个很好的方法。我只会更改子选择中的“where”,以便每次都不重复键,而是直接引用主表。

(select count .. from results where BuildID = r1.BuildID and Verdict  ..)
from results r1

答案 2 :(得分:0)

首先,由于您在评论中提到dbresultsid是一个关键列,  将它包含在group by子句中是无效的,您将为原始表中的每一行(与您的where子句匹配)获得一个输出行。

其次,由于第一个查询中的子查询是 不相关 ,因此它们的输出不依赖于外部查询中的行。因此,它们只会执行一次, 相同 生成的值将在每个输出行中重复。

那么,如果第一个查询的输出真的是你想要的(结果表中每个原始'Beta1'行有一行,输出中的每一行在最后4列中都有相同的值)那么你是什么你可以做到最好。只需取出group by子句 - 你不需要它。

Select 
  dbresultsid, TestCase, BuildID, Analyzed, Verdict,  
  z.PASS, z.FAIL, z.INCONC, z.TIMEOUT
From results r Cross Join 
  (Select 
     Sum(case when Verdict='PASS' then 1 else 0 end) PASS,
     Sum(case when Verdict='FAIL' then 1 else 0 end) FAIL,
     Sum(case when Verdict='INCONC' then 1 else 0 end) INCONC,
     Sum(case when Verdict='TIMEOUT' then 1 else 0 end) TIMEOUT
   From results Where BuildID = 'Beta1') Z
Where BuildID = 'Beta1'
Order By Analyzed