对不起这个问题的通用标题,但我不知道怎么回事......所以这里有:
我有一个表格,其中包含以下信息:
computerName | userName | date | logOn | startUp
| | | |
ID_000000001 | NULL | 2012-08-14 08:00:00.000 | NULL | 1
ID_000000001 | NULL | 2012-08-15 09:00:00.000 | NULL | 0
ID_000000003 | user02 | 2012-08-15 19:00:00.000 | 1 | NULL
ID_000000004 | user02 | 2012-08-16 20:00:00.000 | 0 | NULL
computername和username是不言自明的我想
当用户在计算机上登录时, logOn
为1
,当他注销时,0
为startUp
。
1
为0
,关机时为NULL
。
另一个条目分别是1
,因为我们无法在同一时间登录和启动。
现在我的任务是:找出上个月(或任何给定的时间内,> > > 甚至可以使用SQL? < - 小心:我不需要知道PC打开了多少次,但是在给定时间内每台计算机打开了多少小时/分钟
还有两个小问题:
我们无法说每台计算机的第一个条目是startUp
列中的date
,因为记录这些事件的脚本最近安装了,因此可能是计算机它开始记录时已经在运行。
我们不能假设我们按startUp
订购,并且仅显示userName
列,条目将全部交替为1和0,因为如果计算机被强行关闭例如,拔下插头就不会有关机的日志,连续可能有两个1。
编辑:当startUp
有值时,{{1}}当然是NULL,因为打开/关闭不会显示哪个用户这样做了。
答案 0 :(得分:1)
您可以按计算机进行分组,并使用在特定月份过滤初创公司的位置:
select computerName
, count(*)
from YourTable
where '2012-08-01' <= [date] and [date] < '2012-09-01'
and startup = 1
group by
computerName
order by
count(*) desc
答案 1 :(得分:1)
在存储过程中,使用游标和获取循环。 并且您使用temptable通过computername存储正常运行时间。 我给你主要的计划,我会让你看到TSQL guide中的详细信息。
另一个链接:good example with TSQL Cursor。
DECLARE @total_hour_by_computername
declare @computer_name varchar(255)
declare @RowNum int
--Now in you ComputerNameList cursor, you have all different computernames:
declare ComputerNameList cursor for
select DISTINCT computername from myTable
-- We open the cursor
OPEN ComputerNameList
--You begin your foreach computername loop :
FETCH NEXT FROM ComputerNameList
INTO @computer_name
set @RowNum = 0
WHILE @@FETCH_STATUS = 0
BEGIN
SET @total_hour_by_computername=0;
--This query selects all startup 1 dates by computername order by date.
select @current_date=date from myTable where startup = 1 and computername = @computername order by date
--You use a 2nd loop on the dates that were sent you back:
--This query gives you the previous date
select TOP(1) @previousDate=date from myTable
where computername = @computername and date < @current_date and startup is not null
order by date DESC
--If it comes null, you can decide not to take it into account.
--Else
SET @total_hour_by_computername=@total_hour_by_computername+datediff(hour, @previousDate, @current_date);
--Once all dates have been parsed, you insert into your temptable the results for this computername
INSERT INTO TEMPTABLE(Computername,uptime) VALUES (@computername,@total_hour_by_computername)
--End of the @computer_name loop
FETCH NEXT FROM ComputerNameList
INTO @computer_name
END
CLOSE ComputerNameList
DEALLOCATE ComputerNameList
您只需要选择一个临时表来确定哪一台计算机的时间最长。
答案 2 :(得分:1)
正如RoadWarrior指出的那样,当关闭消息时,无法获得准确的报告。但这是尝试生成有用的东西。我将假设表名为computers
:
SELECT c1.computerName,
timediff(MIN(c2.date), c1.date) as upTime
FROM computers as c1, computers as c2
WHERE c1.computerName=c2.computerName
AND c1.startUp=1 AND c2.startUp=0
AND c2.date >= c1.date
GROUP BY c1.date
ORDER BY c1.date;
这将生成计算机所在时段的列表。要生成您请求的报告,您可以将上述查询用作子查询:
SELECT
c3.computerName,
SEC_TO_TIME(SUM(TIME_TO_SEC(c3.upTime))) AS totalUpTime
FROM
(SELECT c1.computerName,
timediff(MIN(c2.date), c1.date) AS upTime
FROM computers AS c1, computers AS c2
WHERE c1.computerName=c2.computerName
AND c1.startUp=1 AND c2.startUp=0
AND c2.date >= c1.date
GROUP BY c1.date
ORDER BY c1.date
) AS c3
GROUP BY c3.computerName
ORDER BY c3.totalUpTime;
答案 3 :(得分:0)
尝试此查询(将table_name
替换为您的表名称):
SELECT SUM(startUp) AS startupTimes
FROM table_name
GROUP BY computerName
ORDER BY startupTimes
这将输出每台计算机的启动次数。要获得第一行(具有最少启动量的计算机),您可以将LIMIT 1
附加到查询中。
答案 4 :(得分:0)
如果(根据您的最后一段)您没有记录所有关闭事件。然后,您没有可用的信息来生成显示每台计算机已打开的时间的报告。因为您没有记录所有计算机关闭实例,所以使用哪种SQL查询并不重要。
FWIW,此架构不是3NF。更常见的方法是使用单个列记录每个事件,例如:
ComputerId:用户ID:EVENTID:EVENTDATE
前三列分别是存储详细信息的另一个表中的外键。虽然使用此架构,但启动/关闭事件的UserID将为null。