SQL查询-如何限制行I';我对……感兴趣

SQL查询-如何限制行I';我对……感兴趣,sql,tsql,inner-join,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

我有下面的表格——简化了很多

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
我不想要这些,因为这不是最后的结果


我如何限制这一点,以便在以后不进行大量数据操作(或者更糟糕的是,更多的数据库读取)的情况下提供我所需要的信息?任何帮助都将不胜感激。谢谢

我无法对其进行语法检查,但它应该已关闭:

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'
说明:首先,在子查询中,您将获得测试的最大版本。然后使用联接限制外部查询只返回与子查询的测试/版本匹配的结果

Edit:忘记WHERE子句——似乎您只需要最新结果为failure的行

根据您评论中的问题进行编辑:

这将为您提供最近的失败,以及从未运行过的测试。请注意,这将过滤掉已运行但从未失败的测试(您的数据中没有这些测试)。出于时间的考虑,我基于我最初的查询,但我想有一种更优雅的方式:

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

我无法对其进行语法检查,但它应该已关闭:

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'
说明:首先,在子查询中,您将获得测试的最大版本。然后使用联接限制外部查询只返回与子查询的测试/版本匹配的结果

Edit:忘记WHERE子句——似乎您只需要最新结果为failure的行

根据您评论中的问题进行编辑:

这将为您提供最近的失败,以及从未运行过的测试。请注意,这将过滤掉已运行但从未失败的测试(您的数据中没有这些测试)。出于时间的考虑,我基于我最初的查询,但我想有一种更优雅的方式:

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
那么:

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);
那么:

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);

可在上述溶液中添加少量修正。 如果您需要接收测试顺序中的结果,可以按如下方式转换查询:

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;

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

可以在上述解决方案中添加少量更正。 如果您需要接收测试顺序中的结果,可以按如下方式转换查询:

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;

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

为什么测试
A
的第一个版本
通过
,第二个版本
失败
?不应该先是
失败
,然后是
通过
?@BogdanSahlean-不,因为我可以在版本1上运行测试A,然后在版本2上通过并运行,然后失败。版本1、2、…、x是不同版本的软件,例如…但不一定是。为什么测试
A
的第一个版本
通过
,第二个版本
失败
?不应该先是
失败
,然后是
通过
?@BogdanSahlean-不,因为我可以在版本1上运行测试A,然后在版本2上通过并运行,然后失败。版本1,2,…,x是不同版本的软件,例如…但不一定是。是的…谢谢,菲尔。我只是添加了另一个内部连接,以从测试表中获取所需的其余信息,然后bam…它成功了。所有的答案实际上都是有效的,但这一个对我来说更直接,更容易使用我拥有的数据查询对象实现。谢谢菲尔,如果你不介意的话,还有一个问题吗?如果我还想获得尚未运行的测试,我将如何修改它?(所以,类似于我在上面的查询中选择的内容)。是的……完美!谢谢你,菲尔……我非常感激。这正是我所需要的。如果我能给你20票,我会的。是的……谢谢,菲尔。我只是添加了另一个内部连接,以从测试表中获取所需的其余信息,然后bam…它成功了。所有的答案实际上都是有效的,但这一个对我来说更直接,更容易使用我拥有的数据查询对象实现。谢谢菲尔,如果你不介意的话,还有一个问题吗?如果我还想获得尚未运行的测试,我将如何修改它?(所以,类似于我在上面的查询中选择的内容)。是的……完美!谢谢你,菲尔……我非常感激。这正是我所需要的。如果我能给你20票,我会的。