即使结果为null,SQL Query也需要返回行

时间:2014-04-10 19:28:25

标签: sql sql-server-2008 join

我一直用直接的SQL替换一组CLR存储过程,但我一直坚持这个报告。

系统在事件发生时将条目输入到统计表中。如果特定事件没有发生,则HourlyStats表中没有条目。

Table HourlyStats
    UserID    TimeStamp     EventID  Duration
      1       (datetime)       5        36
      2       (datetime)       1       259
      1       (datetime)       2        72
      3       (datetime)       5        36

我们假设表格类别中有5种不同的eventID

 Table Categories
       EventID   Description
           1        Break
           2        Supervision
           3        Lunch
           4        Outbound
           5        Inbound

还有一个用户表

Users
UserID  Name
  1     Tom
  2     Mary
  3     George
  4     Carly

,输出必须如下:

UserID    Description     Sum(TimeSec)
 Tom          Break           Null
 Tom         Supervision       72
 Tom         Lunch            Null
 Tom         Outbound         Null
 Tom         Inbound           36
 Mary        Break            259

我尝试了各种各样的连接,但没有得到我想要的结果。

我可能无法通过单个查询直接执行此操作。我的下一个方法是构造一个临时表,其结构类似于Output表,但是SUM列的值为NULL,然后用结果更新表。

我尝试了很多变化。这是我开始的地方

SELECT HourlyStats.UserID, Categories.Description, SUM(HourlyStats.Duration) AS Expr1
FROM Categories FULL OUTER JOIN
HourlyStats ON Categories.EventID = HourlyStats.EventID
Group by UserID, Description
Order by UserID 

有什么建议吗?

3 个答案:

答案 0 :(得分:1)

你走了:

SELECT u.Name, c.[Description], hs.Duration
FROM Users u
CROSS JOIN Categories c
LEFT OUTER JOIN HourlyStats hs
ON u.UserID = hs.UserID
AND c.EventID = hs.EventID

答案 1 :(得分:1)

您需要CROSS JOIN来获得USERSEVENTS以及LEFT加入HourlyStats代码的所有可能组合将是这样的

;WITH   base
          AS (
               SELECT u.UserID
                   ,u.name
                   ,c.EventId
                   ,c.Description
                FROM Categories AS c
                CROSS JOIN Users AS u
             )
    SELECT b.name
           ,b.Description
           ,SUM(hs.Duration) OVER ( PARTITION BY hs.UserId, hs.EventID ) AS SumTime
        FROM Base AS b
        LEFT JOIN hourlyStats AS hs
            ON b.UserID = hs.UserId
               AND b.EventId = hs.EventID
        ORDER BY 1 DESC
       ,2 ASC

答案 2 :(得分:1)

您需要交叉加入用户和类别,然后在每小时统计信息中加入。这应该做到。

select u.Name, c.Description, sum(hs.Duration)
from Users u
cross join Categories c
left join HourlyStats hs on hs.UserId = u.UserId and hs.EventId = c.EventId
group by u.Name, c.Description
order by u.Name, c.Description

SQL Fiddle