2

我有几张桌子要处理。一个是这样的:

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_startschedule_stopschedule_stop

所以我需要dbo.userActivity根据时间计算在“之前”、“期间”、“之后”、“其他”的值上附加一列。

我真的不确定如何做到这一点,并希望大家能提供任何帮助。

编辑:

好的,所以我大部分时间都在工作。我刚刚看到了一些我将要处理的真实数据,并注意到活动时间是完整的日期时间戳,而活动时间表是及时的。所以我需要将日期时间转换为我可以比较的东西。

这看起来很有效:

SELECT * FROM (SELECT CONVERT(TIME, SCANDATE) as scanTime FROM appData) st WHERE st.scanTime <= '6:00' ORDER BY st.scanTime

举个例子。但是当我尝试像这样将它合并到下面的案例语句中时,它不起作用。它将相同的 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

对此有什么进一步的想法吗?

4

1 回答 1

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 值。如果之前 = 0,期间 = 1,之后 = 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然后,您将使用TimeStatus 参考表获取 UI 的文本值

于 2012-10-17T19:11:44.107 回答