如何在SQL Server中编写此选择查询?

时间:2014-08-05 10:54:04

标签: sql sql-server

我需要提取一些数据来分析异常/日志,而我却陷入了困境。

我的表格中包含一个名为CallType的列,其状态可以是成功失败。此表还有一个名为SessionId的列。

我需要这样做:

选择所有SessionId所有CallType = 'A'被标记为成功的所有内容,但至少有一个CallType = 'B'拥有<该会话的强>失败。

会有一个where子句来过滤掉一些东西。

我想的是:

select top 10 *
from Log nolock
where ProviderId=48  -- add more conditions here
group by SessionId
having --? what should go over here?

3 个答案:

答案 0 :(得分:2)

我会在having子句中使用条件聚合执行此操作:

select top 10 *
from Log nolock
where ProviderId=48  -- add more conditions here
group by SessionId
having sum(case when CallType = 'A' and Status = 'Failure' then 1 else 0 end) = 0 and
       sum(case when CallType = 'B' and Status = 'Failure' then 1 else 0 end) > 0 and
       sum(case when CallType = 'A' and Status = 'Success' then 1 else 0 end) > 0;

having子句通过计算满足每个条件的行数来检查三个条件。如果= 0,则不允许记录。如果> 0则需要记录。

  • CallType A没有失败。
  • CallType B至少有一次失败。
  • 至少有一个CallType A成功。

第三个条件含糊不清 - 如果您根据问题确实需要CallType A s在数据中,则不清楚。

答案 1 :(得分:1)

Having子句只能对组内的聚合进行操作,因此这不是正确的方法,因为您要过滤掉要检查的其他行。我会使用EXISTS来解决此问题。

修改:更正了查询

SELECT *
FROM Log L WITH(NOLOCK)
WHERE ProviderId = 48
AND CallType = 'A'
AND Status = 'Success'
AND EXISTS(SELECT * FROM Log WHERE L.SessionId = SessionId AND CallType = 'B' AND Status = 'Failure')  

您实际上可以使用别名EXISTS表(Log)过滤掉查询的aliased L部分中的行,匹配具有相同会话ID的所有行并查看是否有任何匹配您需要的过滤器(通过呼叫类型B失败)

答案 2 :(得分:1)

SELECT *
FROM Log L WITH(NOLOCK)
WHERE  L.CallType='A' 
AND    L.[Status] = 'Success'
AND    L.ProviderId = 48
AND EXISTS (SELECT 1 
            FROM Log 
            WHERE L.SessionID = SessionID
             AND  CallType='B'
             AND  [Status] =  'Failure')