使用不同的WHERE条件加入查询结果

时间:2013-06-05 18:12:54

标签: sql sql-server-2008-r2

是否可以将这两个查询合并为一个?现在,我运行了2个单独的查询,向我展示:

  1. 用户名及其打开的问题数
  2. 用户名及其关闭的问题数
  3. 未解决的问题:

    SELECT FirstName +' ' + LastName AS 'UserName', COUNT(u.UserID) AS IssuesOpened
    FROM Users u
    LEFT OUTER JOIN Issues i ON i.CreatedByUserID = u.UserID
    WHERE i.DateCreated BETWEEN '06/30/2012 23:59:59' AND '07/01/2013 00:00:01'
    GROUP BY LastName, FirstName
    

    结果看起来如此:

    UserName | IssuesOpened
    -----------------------
    User 1      10
    User 2      8
    User 3      55
    

    已解决的问题:

    SELECT FirstName +' ' + LastName AS 'UserName', COUNT(u.UserID) AS IssuesClosed
    FROM Users u
    LEFT OUTER JOIN Issues i ON i.ResolvedByUserID = u.UserID
    WHERE ResolvedDate BETWEEN '06/30/2012 23:59:59' AND '07/01/2013 00:00:01'
    GROUP BY LastName, FirstName
    

    结果看起来如此:

    UserName | IssuesClosed
    -----------------------
    User 1      8
    User 2      2
    User 3      40
    

    我想加入这两个问题来解决这个问题:

    UserName | IssuesOpened | IssuesClosed
    --------------------------------------
    User 1      10              8
    User 2      8               2
    User 3      55              40
    

    我尝试了一些丑陋的东西,比如:

    SELECT FirstName + ' ' + LastName AS UserName,
        (SELECT COUNT(u.UserID)
        FROM Users u
        LEFT OUTER JOIN Issues i ON i.ResolvedByUserID = u.UserID
        WHERE ResolvedDate BETWEEN '06/30/2012 23:59:59' AND '07/01/2013 00:00:01')
        AS IssuesClosed,
        (SELECT COUNT(u.UserID)
            FROM Users u
            LEFT OUTER JOIN Issues i ON i.CreatedByUserID = u.UserID
            WHERE i.DateCreated BETWEEN '06/30/2012 23:59:59' AND '07/01/2013 00:00:01')
        AS IssuesOpened
    FROM Users u
    GROUP BY FirstName, LastName
    

    但是因为我删除了每个子查询中的GROUP BY子句,所以它只返回总行数。

    更新

    由于我无法将数据加载到SqlFiddle中(查询窗口和架构窗口都只能容纳8000个字符),我想出了一些关于我的结果与sgeddes结果的截图:

    我的结果 PhotoBucket Link to larger image: My Results

    sgeddes结果 SGEDDES Results

    有一件事对我来说就是如果你注意到sgeddes结果,最后一行,用户“Web ***”有449表示“已关闭”。这是不可能的,因为该用户(Web ***)是我们如何确定客户如何通过我们的网站解决问题的占位符。这个虚假用户无法访问我们的系统,也无法关闭任何票证。

2 个答案:

答案 0 :(得分:0)

这可以使用COUNTCASE

一起使用
SELECT FirstName +' ' + LastName AS 'UserName', 
    COUNT(CASE WHEN i.DateCreated BETWEEN '06/30/2012 23:59:59' AND '07/01/2013 00:00:01' 
               THEN 1 END) AS IssuesOpened, 
    COUNT(CASE WHEN ResolvedDate BETWEEN '06/30/2012 23:59:59' AND '07/01/2013 00:00:01' 
               THEN 1 END) AS IssuesClosed
FROM Users u
    LEFT OUTER JOIN Issues i ON i.CreatedByUserID = u.UserID OR i.ResolvedByUserID = u.UserID
GROUP BY LastName, FirstName

这将返回所有用户 - 因此有些人可能会计为0.如果您不想要所有用户,则可以使用WHERE上方OR添加GROUP BY条件。 1}}。在执行此操作时,您否定了需要OUTER JOIN的原因,因此我会将其更改为INNER JOIN

SELECT FirstName +' ' + LastName AS 'UserName', 
    COUNT(CASE WHEN i.DateCreated BETWEEN '06/30/2012 23:59:59' AND '07/01/2013 00:00:01' 
           THEN 1 END) AS IssuesOpened, 
    COUNT(CASE WHEN ResolvedDate BETWEEN '06/30/2012 23:59:59' AND '07/01/2013 00:00:01' 
           THEN 1 END) AS IssuesClosed
FROM Users u
    INNER JOIN Issues i ON 
         i.CreatedByUserID = u.UserID OR i.ResolvedByUserID = u.UserID
WHERE i.DateCreated BETWEEN '06/30/2012 23:59:59' AND '07/01/2013 00:00:01'
    OR ResolvedDate BETWEEN '06/30/2012 23:59:59' AND '07/01/2013 00:00:01'
GROUP BY LastName, FirstName

BTW - 在处理日期字段时,我建议使用> =和<因此而不是BETWEEN

答案 1 :(得分:0)

我会这样做:

  1. 取消隐藏指定时间段内的所有Issue数据,以便每行只包含用户ID和用户造成的状态更改('Opened''Closed'

  2. 旋转结果集,计算每个用户ID的状态更改。

  3. 将数据集加入Users以访问这些名称。

  4. 这是我在实施上述过程中想出的:

    WITH unpivoted AS (
      SELECT
        x.UserID,
        x.IssueStatusChange
      FROM Issues
      CROSS APPLY (
        VALUES
          (CreatedByUserID,  'Opened', DateCreated),
          (ResolvedByUserID, 'Closed', ResolvedDate)
      ) x (UserID, IssueStatusChange, ChangeDate)
      WHERE x.ChangeDate BETWEEN '06/30/2012 23:59:59'
                             AND '07/01/2013 00:00:01'
    ),
    pivoted AS (
      SELECT
        UserID,
        Opened,
        Closed
      FROM unpivoted
      PIVOT (COUNT(IssueStatusChange)
      FOR IssueStatusChange IN (Opened, Closed)) p
    ),
    SELECT
      UserName = u.FirstName + ' ' + u.LastName,
      p.Opened,
      p.Closed
    FROM Users u
    INNER JOIN pivoted p ON u.UserID = p.UserID
    ;
    

    如果有人感兴趣的话,这个查询还有一个SQL Fiddle demo,虽然测试数据集不是很显着(但是可以看到工作中的东西)。

相关问题