返回结果,其中包含来自1个字段的不同ID,来自第2个字段的最大ID,以及来自第3个字段的特定值的过滤

时间:2016-05-05 15:14:09

标签: sql-server

我一直在尝试构建一个查询来报告测试用例的执行情况。这是一个非常简化的数据集,我将用作例子:

TestCase id Test Case Name Execution id Attribute Result 1 Log in to machine 1 Windows 7 Pass 1 Log in to machine 2 Windows 8 Fail 1 Log in to machine 3 Windows 10 Pass 2 Log out of machine 4 Windows 7 Pass 3 Do crazy hacker stuff on machine 5 Windows 7 Pass 2 Log out of machine 6 Windows 8 Pass 3 Do crazy hacker stuff on machine 7 Windows 8 Pass 2 Log out of machine 8 Windows 10 Pass 3 Do crazy hacker stuff on machine 9 Windows 10 Pass 3 Do crazy hacker stuff on machine 10 Windows 8 Pass 1 Log in to machine 11 Windows 8 Fail 2 Log out of machine 12 Windows 8 Pass

我希望能够以这种方式返回一些内容(我知道这不是有效的SQL,但更像是伪SQL):

SELECT DISTINCT(Test Case id), Test Case Name, Attribute, Result
WHERE Attribute=<some attribute to report on> AND Max(Execution id)
ORDER BY Test Case id

每当我尝试这个时,我都会遇到两个问题。

  • 第一个只返回不同的测试用例id。我最接近这样做的是使用group by但是它要求我将结果包含在group by子句中,它给出了最后一次传递结果和最后一次失败的结果(我不想要两者......只是最后一次结果)。
  • 我遇到的另一个问题是尝试使用Max(执行ID)。我不是SQL方面的专家,并尝试过不同的方法来做到这一点,但收效甚微。

我已尝试将其包含在where子句中,having子句中,并使用子查询。我已经阅读了一些关于分区条款的内容,但我对它们并不熟悉,也没有让它工作。

以下是我希望从上面的数据集返回但没有执行ID的伪SQL语句。我不关心是否返回执行id,我只是将它包括在内以区分这个问题的行(我正在使用的数据集要复杂得多,所以希望我没有错过任何约束):

Select distinct(Test Case id), Test Case Name, Attribute, Result
Where Attribute=Windows 7 AND Max(Execution id)
Order By Test Case id

TestCase id Test Case Name Attribute Result Execution id 1 Log in to machine Windows 7 Pass 1 2 Log out of machine Windows 7 Pass 4 3 Do crazy hacker stuff on machine Windows 7 Pass 5

Select distinct(Test Case id), Test Case Name, Attribute, Result
Where Attribute=Windows 8 AND Max(Execution id)
Order By Test Case id

TestCase id Test Case Name Attribute Result Execution id 1 Log in to machine Windows 8 Fail 11 2 Log out of machine Windows 8 Pass 12 3 Do crazy hacker stuff on machine Windows 8 Pass 10

Select distinct(Test Case id), Test Case Name, Attribute, Result
Where Attribute=Windows 10 AND Max(Execution id)
Order By Test Case id

TestCase id Test Case Name Attribute Result Execution id 1 Log in to machine Windows 10 Pass 3 2 Log out of machine Windows 10 Pass 8 3 Do crazy hacker stuff on machine Windows 10 Pass 9

关于我可以尝试的其他事情的任何想法?我错过了一些简单的东西吗?或者这是不可能做到的?

我想知道我是否可以使用结果,我得到最后一次传递和最后一次失败并使用一些逻辑来比较哪个有更大的exec id并且只显示一个但我不确定你是否可以甚至只用SQL做那种东西。

我不是在寻找具有超强性能的东西,只是因为它只会用于报告而不需要经常运行。

3 个答案:

答案 0 :(得分:1)

你应该使用像@podiluska建议的Row_Number。

;WITH cte AS 
(
    SELECT  *, 
            ROW_NUMBER() OVER (PARTITION BY [TestCase id], [Attribute] ORDER BY [Execution id] DESC) Rn 
    FROM    Table1
    -- WHERE Attribute = can go here
)
SELECT * FROM cte
WHERE Rn = 1 -- Top result ordered by [Execution id] Desc

答案 1 :(得分:0)

这感觉就像某种SQL测试。这就是我在解释你的伪sql代码时提出的问题&#39;:

问题1:

Select distinct(Test Case id), Test Case Name, Attribute, Result
Where Attribute=Windows 7 AND Max(Execution id)
Order By Test Case id

答案1:

SELECT [Test Case id], [Test Case Name], Attribute, Result, Max([Execution id]) AS [Max Execution id]
FROM TableName
WHERE Attribute = 'Windows 7'
GROUP BY [Test Case id], [Test Case Name], Attribute, Result

答案2: (与问题1相同,只有不同的WHERE子句):

SELECT [Test Case id], [Test Case Name], Attribute, Result, Max([Execution id]) AS [Max Execution id]
FROM TableName
WHERE Attribute = 'Windows 8'
GROUP BY [Test Case id], [Test Case Name], Attribute, Result
ORDER BY [Test Case id]

问题3: 选择distinct(测试用例ID),测试用例名称,属性,结果 其中Attribute = Windows 10 AND Max(执行ID) 按测试用例ID排序

答案3: (与问题2相同,只有不同的WHERE子句):

SELECT [Test Case id], [Test Case Name], Attribute, Result, Max([Execution id]) AS [Max Execution id]
FROM TableName
WHERE Attribute = 'Windows 10'
GROUP BY [Test Case id], [Test Case Name], Attribute, Result
ORDER BY [Test Case id]
  

我想知道是否可以使用我得到的两个结果   传递和最后失败并使用一些逻辑来比较哪个有   更大的执行者只显示一个,但我不确定你是否可以   只用SQL做那种东西。

  • 您当然可以在单个查询(使用子查询)或一系列查询中执行此类操作。你只需要嵌套它们或者适当地订购它们。

答案 2 :(得分:0)

您还可以将LAST_VALUE函数与OVER子句一起使用。

创建并填充表格。

CREATE TABLE dbo.TestCase
(
    ExecutionId int NOT NULL PRIMARY KEY,
    TestCaseId int NOT NULL,
    TestCaseName nvarchar(100) NOT NULL,
    Attribute nvarchar(50) NOT NULL,
    Result nvarchar(4) NOT NULL
);
GO

INSERT INTO dbo.TestCase (TestCaseId, TestCaseName, ExecutionId, Attribute, Result)
    VALUES
    (1, N'Log in to machine', 1 , N'Windows 7', N'Pass'),
    (1, N'Log in to machine', 2 , N'Windows 8', N'Fail'),
    (1, N'Log in to machine', 3 , N'Windows 10', N'Pass'),
    (2, N'Log out of machine', 4 , N'Windows 7', N'Pass'),
    (3, N'Do crazy hacker stuff on machine', 5, N'Windows 7', N'Pass'),
    (2, N'Log out of machine', 6 , N'Windows 8', N'Pass'),
    (3, N'Do crazy hacker stuff on machine', 7, N'Windows 8', N'Pass'),
    (2, N'Log out of machine', 8 , N'Windows 10', N'Pass'),
    (3, N'Do crazy hacker stuff on machine', 9, N'Windows 10', N'Pass'),
    (3, N'Do crazy hacker stuff on machine', 10, N'Windows 8', N'Pass'),
    (1, N'Log in to machine', 11, N'Windows 8', N'Fail'),
    (2, N'Log out of machine', 12, N'Windows 8', N'Pass');

然后是带有CTE的SELECT语句。

WITH cte AS
(
    SELECT TestCaseId, TestCaseName, Attribute, ExecutionId, LAST_VALUE(Result) OVER(PARTITION BY TestCaseId, TestCaseName, Attribute ORDER BY ExecutionID) AS 'LastResult'
        FROM dbo.TestCase
)
SELECT TestCaseId, TestCaseName, Attribute, LastResult
    FROM cte
    GROUP BY TestCaseId, TestCaseName, Attribute, LastResult
    ORDER BY TestCaseId, Attribute;

enter image description here