MS SQL加入/计数查询

时间:2016-07-31 22:53:52

标签: sql

我有以下表格:

会话

  • Id(int)
  • UserId(int)
  • 开始(日期时间)
  • 停止(日期时间)

用户

  • Id(int)
  • 用户名(nvarchar(200))

日志

  • SessionId(int)
  • LogLevelId(int)
  • 时间戳(日期时间)
  • 消息(varchar(max))

记录级

  • Id(int)
  • DisplayText(varchar(5))

我想要的是一个输出,它显示了包含以下列的会话列表的概述:

SessionId | Username | Start | Stop | [total number of logs from each log level]

我在C#I中有一个解决方案:

  1. 选择所有日志级别及其关联的显示文本
  2. 使用以下查询获取所有会话的列表:
  3. -

    SELECT [Sessions].[Id]
          ,[Username]
          ,[Start]
          ,[Stop]
          ,[Application]
      FROM [Sessions]
      JOIN [Users] ON [Users].[Id] = [UserId]
    
    1. 我遍历步骤1中的每个结果,以汇编查询以计算每个可能的日志级别。然后根据步骤2的每个结果执行查询,将end子句放在最后根据特定会话进行过滤。每个查询看起来如下所示:
    2. -

      SELECT 
           COUNT(CASE [Logs].[LogLevelId] WHEN 1 THEN 1 END) AS 'Debugs'
          ,COUNT(CASE [Logs].[LogLevelId] WHEN 2 THEN 1 END) as 'Infos'
          ,COUNT(CASE [Logs].[LogLevelId] WHEN 3 THEN 1 END) as 'Warnings'
          ,COUNT(CASE [Logs].[LogLevelId] WHEN 4 THEN 1 END) as 'Errors'
          ,COUNT(CASE [Logs].[LogLevelId] WHEN 5 THEN 1 END) as 'Fatals'
        FROM [Logs]
        WHERE [SessionId] = |C# SESSION ID HERE|
      

      我知道这不是一个最佳解决方案,我想知道如何在单个查询或两个查询中提取所有这些信息而不是2个查询+ N,其中N是总数会话行。

1 个答案:

答案 0 :(得分:3)

考虑在聚合GROUP BY查询中将后一个查询加入以前的查询。

SELECT l.SessionId
       , u.Username
       , s.Start
       , s.Stop
       , COUNT(CASE WHEN l.[LogLevelId] = 1 
                    AND lvl.DisplayText = 'Debugs' THEN 1 END) AS 'Debugs'
       , COUNT(CASE WHEN l.[LogLevelId] = 2 
                    AND lvl.DisplayText = 'Infos' THEN 1 END) as 'Infos'
       , COUNT(CASE WHEN l.[LogLevelId] = 3 
                    AND lvl.DisplayText = 'Warnings' THEN 1 END) as 'Warnings'
       , COUNT(CASE WHEN l.[LogLevelId] = 4 
                    AND lvl.DisplayText = 'Errors' THEN 1 END) as 'Errors'
       , COUNT(CASE WHEN l.[LogLevelId] = 5 
                    AND lvl.DisplayText = 'Fatals' THEN 1 END) as 'Fatals'
FROM     
   [Sessions] s
   JOIN [Users] u ON u.[Id] = s.[UserId]
   JOIN [Logs] l ON l.[SessionId] = s.[Id]
   JOIN [LogLevels] lvl ON lvl.[Id] = l.[LogLevelId]

GROUP BY l.[SessionId]
         , u.Username
         , s.Start
         , s.Stop