我有一个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”的表,它保存月份(月份)和月份名称(MonthName),并尝试在此表上执行左外连接,并尝试使用案例选择。我在Stackoverflow上搜索了这个问题,看到了一些类似的问题,但没有涉及使用日期的问题。今天苦苦思索......
答案 0 :(得分:3)
您可以使用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;
答案 1 :(得分:1)
您使用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
注:
sessionTable
作为主要数据源时,请勿过滤where子句中的month
数据 - 在LEFT OUTER JOIN
中对其进行过滤。如果您将其放在WHERE
中,则会将事情变为INNER JOIN
。months
表格那工作?
答案 2 :(得分:0)
您需要有一个日历表,通常是在某个范围内的预定义日期列表..
您需要有月表来满足您的需求......可以使用数字表生成..
这只是伪代码:
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/