我有几张表要处理。一个是这样的:
dbo.userActivity
userID Action Time
1 25 12:00
1 10 12:01
1 12 12:35
1 6 13:54
2 10 6:47
2 42 6:48
3 8 11:54
etc.
另一张表是一个如下所示的时间表:
dbo.userSchedule
userID schedule_start schedule_stop
1 07:00 09:00
2 11:00 12:30
3 14:00 15:00
etc.
我需要为dbo.userActivity
中的每一行执行的操作是确定每个操作是在schedule_start
之前一小时,在schedule_start
和schedule_stop
次之间,一小时在schedule_stop
之后,或任何其他时间。
所以我需要在dbo.userActivity
附加一个列,其值为“之前”,“期间”,“之后”,“其他”基于时间计算。
我真的不知道该怎么做,并感谢你们所能提供的任何帮助。
编辑:
好的,所以我有大部分工作。我刚刚看到了一些我将要处理的实际数据,并注意到活动时间是完整的日期时间戳,而活动时间表恰好在时间上。所以我需要将日期时间转换为我可以比较的东西。
这看起来很有效:
SELECT * 从 ( SELECT CONVERT(TIME,SCANDATE)as scanTime 来自appData )st 在哪里st.scanTime< ='6:00' ORDER BY st.scanTime
仅作为一个例子。但是当我尝试将其合并到下面的case语句中时,它就不起作用了。它对每一行应用相同的THEN。
SELECT CASE WHEN EXISTS ( SELECT * FROM ( SELECT CONVERT(TIME, SCANDATE) as scanTime FROM appData ) st WHERE st.scanTime <= '6:00' ) THEN 'Before 6 am' ELSE '6 am or after' END FROM appData
对此有何进一步的想法?
答案 0 :(得分:1)
首先,您需要将列(NULL
)添加到表中。
ALTER TABLE dbo.UserActivity
ADD TimeStatus VARCHAR(6) NULL;
接下来,您将编写更新查询。它可以用CASE
语句编写:
UPDATE ua
SET ua.TimeStatus =
CASE
WHEN CAST(ua.Time AS TIME) >= us.Schedule_Start
AND CAST(ua.Time AS TIME) <= us.Schedule_stop THEN 'During'
WHEN CAST(ua.Time AS TIME) >= DATEADD(HOUR, -1, us.Schedule_Start)
AND CAST(ua.Time AS TIME) <= us.ScheduleStart THEN 'Before'
WHEN CAST(ua.Time AS TIME) >= us.Schedule_Stop
AND CAST(ua.Time AS TIME) <= DATEADD(HOUR, 1, us.Schedule_Stop)
THEN 'After'
ELSE 'Other'
END
FROM dbo.UserActivity AS ua
INNER JOIN dbo.userSchedule AS us ON ua.UserId = us.UserId
如果所有列都包含数据,则可以将列设置为NOT NULL
,如果您已更新应用程序以了解并填充此新列。
我还会考虑不将字符串值存储在此表中,而是将较小的值存储在引用表的外键中。只有4个值,您可以使用TINYINT
并为您存储的每个dbo.UserActivity记录节省空间。
如果您决定使用此路线,则只需从参考表中获取值,并将字符串值替换为ID值。如果Before = 0,则在= 1,After = 2,其他= 3
UPDATE ua
SET ua.TimeStatusId =
CASE
WHEN CAST(ua.Time AS TIME) >= us.Schedule_Start
AND CAST(ua.Time AS TIME) <= us.Schedule_stop THEN 1
WHEN CAST(ua.Time AS TIME) >= DATEADD(HOUR, -1, us.Schedule_Start)
AND CAST(ua.Time AS TIME) <= us.ScheduleStart THEN 0
WHEN CAST(ua.Time AS TIME) >= us.Schedule_Stop
AND CAST(ua.Time AS TIME) <= DATEADD(HOUR, 1, us.Schedule_Stop)
THEN 2
ELSE 3
END
FROM dbo.UserActivity AS ua
INNER JOIN dbo.userSchedule AS us ON ua.UserId = us.UserId
然后,您将获得带有INNER JOIN
的UI的文本值到您的TimeStatus参考表