【问题标题】:Showing month value when no data exists SQL Server不存在数据时显示月份值 SQL Server
【发布时间】:2016-04-25 15:54:19
【问题描述】:

我有一个 SQL Server 2012 表,其中包含每个用户的会话,我需要找出每月的活动总分钟数,如果当月没有结果,则显示“0”。下表:

User   SessionStart              SessionEnd
1      2014-03-01 08:00:00.000   2014-03-01 08:10:00.000
1      2014-03-15 09:00:00.000   2014-03-15 09:30:00.000
1      2014-05-01 04:00:00.000   2014-05-01 04:50:00.000
1      2014-06-01 02:00:00.000   2014-06-01 02:05:00.000
1      2014-07-01 09:00:00.000   2014-07-01 10:30:00.000
1      2014-09-01 01:00:00.000   2014-09-01 01:07:00.000
1      2014-12-05 08:00:00.000   2014-12-05 08:10:00.000
2      2014-01-01 01:01:00.000   2014-01-01 01:11:00.000
1      2015-03-01 08:00:00.000   2015-03-01 08:10:00.000
1      2015-05-01 04:00:00.000   2015-05-01 04:50:00.000
1      2015-06-01 02:00:00.000   2015-06-01 02:05:00.000
...    ...                       ...

我的结局是:

User   Month   Year   Minutes 
1      3       2014   40
1      5       2014   50  
1      6       2014   5
1      7       2014   90
1      9       2014   7
1      12      2014   10
1      3       2015   10
1      5       2015   50
1      6       2015   5

我想得到什么:

User   Month   Year   Minutes 
1      1       2014   0
1      2       2014   0
1      3       2014   40
1      4       2014   0
1      5       2014   50  
1      6       2014   5
1      7       2014   90
1      8       2014   0
1      9       2014   7
1      10      2014   0
1      11      2014   0
1      12      2014   10
1      1       2015   0
1      1       2015   0
1      3       2015   10
1      4       2015   0
1      5       2015   50
1      6       2015   5

我尝试过使用:

SELECT User
      ,MONTH(SessionStart)
      ,YEAR(SessionStart)
      ,SUM(DATEDIFF(minute, SessionStart, SessionEnd)) AS Minutes
FROM SessionTable
WHERE User = 1 AND YEAR(SessionStart) >= 2014
GROUP BY SessionStart, User

我有一个名为“Months”的表,其中包含月份的编号 (Month) 和月份的名称 (MonthName),并尝试在此表上执行左外连接,并尝试使用案例选择。我在 Stackoverflow 上搜索了这个问题,看到了一些类似的问题,但没有涉及使用日期的问题。今天在努力思考......

【问题讨论】:

  • 您是否尝试从Months 表中进行选择,然后使用LEFT OUTER JOIN 到您的SessionTable (IMO 的表名不好——当然是“表”)?

标签: sql sql-server datetime


【解决方案1】:

您可以使用cross join 生成所有行,然后使用left join 引入您的摘要。假设每个月都存在一些行,您可以从会话表本身获取此信息:

SELECT u.User, yyyymm.mm, yyyymm.yy
       COALESCE(SUM(DATEDIFF(minute, s.SessionStart, s.SessionEnd)), 0) AS Minutes
FROM (SELECT 1 as user) u CROSS JOIN
     (SELECT DISTINCT YEAR(SessionStart) as yyyy, MONTH(SessionStart) as mm
      FROM SessionTable
      WHERE SessionStart >= '2014-01-01'
     ) yyyymm LEFT JOIN
     SessionStart ss
     ON u.user = ss.user AND
        YEAR(SessionStart) = yyyymm.yy AND MONTH(SessionStart) = yyyymm.mm
GROUP BY u.User, yyyymm.yyyy, yyyymm.mm;

【讨论】:

  • 到目前为止,这就像一个冠军。我确实有数千行,并且能够从自身中提取年/月。从来没有想过这样的事情!我改变了几个变量,它完全按照我希望的方式拉动......
【解决方案2】:

您的months 表走在正确的轨道上。您能否发布使用左外连接不起作用的示例?如果您以months 开头,然后将外部连接左外部连接到您的SessionTable,您应该没问题。

类似...

SELECT User
      ,MONTH(m.month)
      ,YEAR(m.year)
      ,SUM(DATEDIFF(minute, s.SessionStart, s.SessionEnd)) AS Minutes
FROM Months m
  LEFT OUTER JOIN SessionTable s
    ON m.year = s.year
    AND m.month = s.month
    AND s.User = 1 
WHERE YEAR(m.year) >= 2014
GROUP BY s.SessionStart, s.User

注意:

  • 当您使用 month 作为主要数据源时,不要在 where 子句中过滤您的 sessionTable 数据 - 在 LEFT OUTER JOIN 中过滤它。如果你把它放在WHERE 中,你就把它变成了INNER JOIN
  • 您希望在返回月/年信息的数据时使用 months

那行吗?

【讨论】:

  • 很遗憾,我没有列出年份的表格。在您的示例中,您让我在“月份”表上匹配年份。使用您的示例,我仍然可以在没有我想要“0”的月份的情况下返回数据。我可能还要创建另一个表好几年。
【解决方案3】:

您需要有一个日历表,该表通常是在某个范围内的预定义日期列表..

您需要有月份表以满足您的需要..可以使用数字表生成..

这只是一个伪代码:

create table months
(
monthdate datetime
)

insert into monthdate
select dateadd(day,n,getdate()-10000)
from numbers
where n<=10000

现在你有了月份表,你需要做的就是左连接

select *
from monthstable mt
join yourtable yt
on yt.date=mt.date

这样您将保留所有您没有的日期

** 一些不错的链接:**
http://www.sqlservercentral.com/blogs/dwainsql/2014/03/30/calendar-tables-in-t-sql/

http://www.sqlservercentral.com/articles/T-SQL/62867/

【讨论】:

    猜你喜欢
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多