0

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

  1. 用户名以及他们打开了多少个问题
  2. 用户名以及他们关闭了多少个问题

开放式问题:

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 链接到更大的图像: 我的结果

sgeddes 结果 SGEDDES 结果

让我印象深刻的一件事是,如果您注意到 sgeddes 结果,最后一行,用户“Web***”有 449 个“已关闭”。这是不可能的,因为该用户 (Web***) 是我们如何确定客户如何通过我们的网站打开问题的占位符。该假用户无权访问我们的系统,也无法关闭任何工单。

4

2 回答 2

0

我会这样做:

  1. 取消透视指定时间段内的所有Issue数据,以便每一行仅包含用户 ID 和用户引起的状态更改('Opened''Closed')。

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

  3. 加入透视集以Users访问名称。

这是我在实施上述过程中提出的:

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 演示,尽管测试数据集不是很显着(不过可能可以看到正在工作的东西)。

于 2013-06-05T21:26:03.207 回答
0

这应该与使用COUNT一起工作CASE

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在这样做时,您否定了需要 an 的原因OUTER JOIN,所以我会将其更改为 an 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

顺便说一句——在处理日期字段时,我建议相应地使用 >= 和 < 而不是BETWEEN.

于 2013-06-05T18:15:52.320 回答