我在SqlServer中有一个日志文件,它存储应用程序启动的时间,应用程序就绪的时间(即已完成加载)以及退出的时间。每个都作为单独的条目出现。格式(和样本数据)如下:
Date/Time User Type Application Message
2009-11-03 12:26:12.403 uname1 Info app1 Started
2009-11-03 12:26:22.403 uname1 Info app1 Loaded
2009-11-03 12:27:15.403 uname2 Info app1 Started
2009-11-03 12:27:16.401 uname1 Info app1 Exited
2009-11-03 12:27:18.403 uname2 Info app1 Loaded
2009-11-03 12:29:12.403 uname2 Info app1 Exited
我想知道,根据应用程序和每个用户,应用程序进入就绪状态所花费的时间以及应用程序运行的时间。如果每个日期/时间都在同一个记录中,这将是一块蛋糕,并且将每个记录作为光标加载并筛选数据也很容易(虽然单调乏味),但我认为必须有某种方式以集理论的方式“正确地”做到这一点。
因此,重申一下,预期会有以下输出(来自上面的样本数据)(数字以秒为单位,向上舍入):
User Application Ready Uptime
uname1 app1 10 64
uname2 app1 3 117
有什么建议吗?
编辑:好消息是应用程序只能启动一次。但是,如果应用程序崩溃,日志不会考虑(尽管我认为我可以寻找“退出”和“崩溃”作为最终条件)。
答案 0 :(得分:3)
我宁愿不多次加入同一个表,特别是如果表变大了。这是一种双程方法。第一遍将时间排序到正确的位置,第二遍将用户和应用程序折叠起来:
SELECT
User,
Application,
MAX(StartTime) StartTime,
MAX(ReadyTime) ReadyTime,
MAX(ExitTime) ExitTime,
FROM (
SELECT
User,
Application,
CASE (
WHEN Message = 'Started' THEN Date/Time
ELSE NULL
) StartTime,
CASE (
WHEN Message = 'Loaded' THEN Date/Time
ELSE NULL
) ReadyTime,
CASE (
WHEN Message = 'Exited' THEN Date/Time
ELSE NULL
) ExitTime
FROM Log
) Log
GROUP BY
User,
Application
从那里开始,在那些不同的时间计算所有你想要的东西是微不足道的。
它不像“集合论”,但分组和聚合从来都不是。与Eric的解决方案一样,当同一用户多次使用该应用程序时,它无法处理这种情况。您需要第三个分组列(如“会话”或其他内容)来处理该场景。
答案 1 :(得分:2)
怎么样
Select S.user, S.Application,
S.DateTime Started, L.DateTime Loaded, X.DateTime Exited,
L.DateTime - S.DateTime LoadTime,
X.DateTime - L.DateTime RunTime
From LogFile S
Full Join LogFile L
On S.Message = 'Started'
And L.Message = 'Loaded'
And L.User = S.user
And L.Application = S.Application
And L.DateTime = (Select Min(DateTime)
From LogFile
Where Message = 'Loaded'
And application = S.Application
And user = S.user
And DateTime > S.DateTime)
Full Join LogFile X
On L.Message = 'Loaded'
And X.Message = 'Exited'
And X.User = L.user
And X.Application = L.Application
And X.DateTime = (Select Min(DateTime)
From LogFile
Where Message = 'Exited'
And application = L.Application
And user = L.user
And DateTime > L.DateTime)
然后根据需要将聚合函数应用于此:
Select user, Application,
Sum(LoadTime) TotLoadTime,
Sum(RunTime) TotalRunTime
From
(Select S.user, S.Application,
S.DateTime Started, L.DateTime Loaded, X.DateTime Exited,
L.DateTime - S.DateTime LoadTime,
X.DateTime - L.DateTime RunTime
From LogFile S
Full Join LogFile L
On S.Message = 'Started'
And X.Message = 'Loaded'
And L.User = S.user
And L.Application = S.Application
And L.DateTime =
(Select Min(DateTime)
From LogFile
Where Message = 'Loaded'
And application = S.Application
And user = S.user
And DateTime > S.DateTime)
Full Join LogFile X
On L.Message = 'Loaded'
And X.Message = 'Exited'
And X.User = L.user
And X.Application = L.Application
And X.DateTime =
(Select Min(DateTime)
From LogFile
Where Message = 'Exited'
And application = L.Application
And user = L.user
And DateTime > L.DateTime)) Z
Group By user, Application