2

対処するテーブルがいくつかあります。1つは次のようなものです。

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.

もう1つの表は、次のようなスケジュールです。

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のは、各アクションが、の1時間前、との時間schedule_startの間、1時間後、またはその他の時間であったかどうかを判断することです。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

例として。しかし、このように以下の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

これについてさらに考えますか?

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値に置き換えます。Before = 0、during = 1、After = 2、Other=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 に答える