SQL查询 - 如何限制我感兴趣的行

时间:2013-10-27 02:23:53

标签: sql tsql inner-join

我有以下表格 - 简化了很多

Table - Tests
Test
A
B
C
D
E
F
G
H

Table - TestHistory
Test    Result    Version
A       Pass      1
A       Fail      2
B       Pass      2
C       Fail      1
C       Pass      2
D       Fail      1
D       Fail      2
E       Fail      1

我想获取上次运行时失败(或任何状态)的测试列表。但是,也是它的版本。

所以,在上面的例子中,我想要返回:

A    Fail    2
D    Fail    2
E    Fail    1

我尝试了几种方法

select Test, LastResult = IsNull((Select Top 1 Result From TestHistory Where Test = Tests.Test order by Version desc), 'NOT_RUN')
from Tests

这样做,是给我一个所有测试的列表,然后我必须经历并踢出我不想要的行(即不是失败)。这也没有给我它运行的版本。

我也试过这个:

select Version, TH.Test, Result
from TestHistory as TH inner join Tests as T on TH.Test = T.Test
where Result = 'Fail'

但是,我得到的行如下:

Test    Result    Version
C       Fail      1

我不想要那些因为它不是最后结果

如何在没有大量数据操作(或者更糟糕的是,更多数据库读取)的情况下限制它以准确地提供我所需要的内容?任何帮助,将不胜感激。谢谢!

3 个答案:

答案 0 :(得分:2)

我无法对此进行语法检查,但它应该是关闭的:

SELECT
  th.Test,
  th.Result,
  th.Version
FROM
  TestHistory th
  INNER JOIN
    (
      SELECT
      MAX(Version) as MaxVersion,
      Test
    FROM
      TestHistory
    GROUP BY
      Test
    ) sub ON sub.MaxVersion = th.Version AND sub.Test = th.Test
    WHERE 
      th.result = 'Fail'

说明:首先,在子查询中,您将获得测试的最大版本。然后使用连接将外部查询限制为仅返回与子查询的测试/版本匹配的结果。

编辑:忘记了WHERE子句 - 似乎你只想要最近结果失败的行。

根据评论中的问题进行修改:

这应该会给你最近的失败,以及从未运行过的测试。请注意,这将过滤掉运行但从未失败的测试(您的数据没有任何这些)。为了时间的缘故,我基于原始查询,但我猜有更优雅的方式:

SELECT
  t.Test,
  outerSub.Result,
  outerSub.Version  
FROM
  Test t
  LEFT JOIN 
(SELECT
  th.Test,
  th.Result,
  th.Version
FROM
  TestHistory th
  INNER JOIN
    (
      SELECT
      MAX(Version) as MaxVersion,
      Test
    FROM
      TestHistory
    GROUP BY
      Test
    ) sub ON sub.MaxVersion = th.Version AND sub.Test = th.Test
) outerSub on outerSub.Test = t.Test
    WHERE 
      outerSub.result = 'Fail' OR outerSub.Test IS NULL

答案 1 :(得分:2)

可以在上述解决方案中添加小的修正。 如果您需要在测试订单中接收结果,可以按如下方式转换查询:

SELECT src.Test, src.Result, src.Version
FROM
(
    SELECT th.Version, th.Test, th.Result, 
         ROW_NUMBER() over(partition by th.Test order by th.Version desc) as RowNum
    FROM dbo.TestHistory as th
) src
WHERE src.RowNum = 1 and src.Result = 'Fail'
order by src.Test;

其中,查询将以所需列的顺序返回该集。

答案 2 :(得分:1)

怎么样:

select th.* from testHistory th 
where th.result = 'fail' -- this part, according to you, being optional
and th.version = 
    (select max(t.version) from testhistory t 
     where t.test = th.test);