以15分钟为增量进行活动的人数 - SQL Server

时间:2014-03-27 20:10:44

标签: sql sql-server datetime

我在SQL Server中有一个表格,结构如下:

  

ActivityName(varchar),UserId(varchar),ActivityStartTime(varchar),ActivityTimeInMinutes(smallint)

有这个样本数据:

  

烹饪,詹姆斯,1300,60
   清洁,詹姆斯,1400,120
   睡觉,詹姆斯,1600,90
   驾驶,吉尔,1100,120
   清洁,吉尔,1300,30    烹饪,吉尔,1330,45    睡觉,吉尔,1414,120

如何在sql中创建一个表,以15分钟为增量计算每个活动的人数,因此在上面的示例中,这将是1300-1400的条目:

  

TimePeriod,烹饪,清洁,驾驶,睡觉
  1300,1,1,0,0   1315,1,1,0,0   1330,2,0,0,0   1400,1,1,0,0

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

需要旋转数据以获得所需的结果。这个sql假设你只对时间感兴趣(不是日期),并且时间都是格式化的,并且#34; hhmm"。因此,6AM将被渲染为0600.如果不是这种情况,则需要更新此代码以添加额外的零。

-- load your test data
declare @Activity table
    (
    ActivityName varchar(50),
    UserId varchar(50),
    ActivityStartTime varchar(50),
    ActivityTimeInMinutes smallint
    )
insert into @Activity values
    ('Cooking','James','1300',60),
    ('Cleaning','James','1400',120),
    ('Sleeping','James','1600',90),
    ('Driving','Jill','1100',120),
    ('Cleaning','Jill','1300',30),
    ('Cooking','Jill','1330',45),
    ('Sleeping','Jill','1414',120)

-- populate @TimeTable with 15 min increments based on your time data
declare @TimeTable table
    (
    StartTime datetime,
    EndTime datetime
    )
declare @ActivityStartTime datetime,
        @ActivityEndTime datetime
select @ActivityStartTime =
        min(left(ActivityStartTime,2) + ':' + right(ActivityStartTime,2)),
  @ActivityEndTime =
        max(dateadd(minute,ActivityTimeInMinutes,left(ActivityStartTime,2)
        + ':' + right(ActivityStartTime,2)))
from @Activity
while @ActivityStartTime <= @ActivityEndTime
    begin
        insert into @TimeTable values
            (@ActivityStartTime,dateadd(minute,15,@ActivityStartTime))
        set @ActivityStartTime = dateadd(minute,15,@ActivityStartTime)
    end

-- pivot results
select
    replace(left(convert(varchar(8),TimePeriod,108),5),':','') TimePeriod,
    isnull(Cooking,0) Cooking,
    isnull(Cleaning,0) Cleaning,
    isnull(Driving,0) Driving,
    isnull(Sleeping,0) Sleeping
from    (
        select
            t.StartTime TimePeriod,
            a.ActivityName,
            count(a.UserID) Cnt
        from @TimeTable t
            inner join @Activity a
                on cast(left(ActivityStartTime,2) + ':' +
                    right(ActivityStartTime,2) as datetime) < t.EndTime
                and dateadd(minute,a.ActivityTimeInMinutes,
                    cast(left(ActivityStartTime,2) + ':' +
                    right(ActivityStartTime,2) as datetime)) > t.StartTime
        group by 
            t.StartTime,
            a.ActivityName
        ) t
        pivot   (
                sum(Cnt)
                for ActivityName in([Cooking],[Cleaning],[Driving],[Sleeping])
                ) p
order by TimePeriod

答案 1 :(得分:1)

这应该这样做:

SELECT 
    UserId, 
    ActivityName,
    DATETIMEFROMPARTS(
        YEAR(ActivityStartTime),
        MONTH(ActivityStartTime),
        DAY(ActivityStartTime),
        HOUR(ActivityStartTime),
        (MINUTE(ActivityStartTime)/15) * 15,
        0,
        0
    ) AS ActivityStartQtrHour
    SUM(ActivityTimeInMinutes) AS ActivityDurationMinutes
GROUP BY 
    UserId, 
    ActivityName,
    DATETIMEFROMPARTS(
        YEAR(ActivityStartTime),
        MONTH(ActivityStartTime),
        DAY(ActivityStartTime),
        HOUR(ActivityStartTime),
        (MINUTE(ActivityStartTime)/15) * 15,
        0,
        0
    )

没有测试,因为没有测试数据,但无论如何你应该能够遵循它。