0

对不起这个问题的通用标题,但我不知道该怎么说。所以这里是:

我有一个包含以下信息的表:

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

我想计算机名和用户名是不言自明的

logOn1用户在机器上0登录和注销的时间。

startUp1机器打开和0关闭的时间。

另一个条目总是NULL分别,因为我们不能同时登录和启动。

现在我的任务是:找出上个月(或任何给定时间,但现在假设一个月)哪些计算机开启的时间最少。这甚至可以用 SQL 实现吗?<-- 小心:我不需要知道电脑打开了多少次,而是每台电脑在给定的时间空间内打开了多少小时/分钟

还有两个小问题:

我们不能说每台计算机的第一个条目是1列中startUp的,因为记录这些事件的脚本是最近安装的,因此可能在开始记录时计算机已经在运行。

我们不能假设如果我们按顺序排序date并且只显示startUp条目将全部交替为 1 和 0 的列,因为如果通过拔出插头强制关闭计算机,则不会有关闭日志,并且可能连续两个 1。

编辑:userName当有值时当然是 N​​ULL startUp,因为打开/关闭不会显示哪个用户这样做。

4

5 回答 5

1

您可以按计算机分组,并使用 where 筛选特定月份的初创公司:

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
于 2012-08-29T09:17:03.640 回答
1

在存储过程中,带有游标和 fetch 循环。你使用一个 temptable 按计算机名存储正常运行时间。我给你主要计划,我会让你在TSQL 指南中看到细节。

另一个链接: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

您只需要在您的 temptable 中进行选择,以确定哪一台计算机的运行时间最长。

于 2012-08-29T09:52:40.933 回答
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;
于 2012-08-29T09:52:59.453 回答
0

试试这个查询(用table_name你的表名替换):

SELECT SUM(startUp) AS startupTimes 
FROM table_name
GROUP BY computerName
ORDER BY startupTimes

这将输出每台计算机已启动的次数。要仅获取第一行(启动次数最少的计算机),您可以附加LIMIT 1到查询中。

于 2012-08-29T09:17:12.250 回答
0

如果(根据您的最后一段)您没有记录所有关机事件。那么您没有可用的信息来生成显示每台计算机已打开的时间量的报告。因为您没有记录计算机关闭的所有实例,所以您使用什么 SQL 查询并不重要。

FWIW,这个模式不是 3NF。更常见的方法是用一个列记录每个事件,例如:

计算机 ID:用户 ID:事件 ID:事件日期

前三列分别是另一个存储详细信息的表的外键。尽管即使使用此模式,对于启动/关闭事件,用户 ID 也会为空。

于 2012-08-29T09:27:53.757 回答