【问题标题】:SQL Query needs to return rows even when results are null即使结果为空,SQL 查询也需要返回行
【发布时间】:2014-04-10 19:28:25
【问题描述】:

我一直在用直接的 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

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

我可能无法通过单个查询直接执行此操作。我的下一个方法是构建一个结构类似于输出表但 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 

有什么建议吗?

【问题讨论】:

  • 外连接非常可行。如果您显示您的查询会有所帮助,不是吗?
  • 展示你的尝试。 as 能帮到你会很有帮助。
  • 我只是懒得创建所有的表和数据,所以给你一个提示:(Categories CROSS JOIN USERS) LEFT JOIN HourlyStats。可能需要稍作调整才能按要求的顺序获取正确的数据。编辑:如果Users 的列表太大,您可能需要查看其他解决方案。
  • 谢谢,CROSS JOIN 可以解决问题。用户和类别列表相对较少。

标签: sql sql-server-2008 join


【解决方案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

【讨论】:

    【解决方案2】:

    您需要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
    

    【讨论】:

      【解决方案3】:

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

      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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-01-06
        • 1970-01-01
        • 1970-01-01
        • 2014-06-04
        • 2019-08-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多