2012-10-17 99 views
2

我有幾個表來處理。一個是這樣的:SQL Server:如何遍歷行並賦值

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是確定每個動作是否是一個小時b在schedule_start之前,在schedule_startschedule_stop之間,在schedule_stop之後一小時,或者任何其他時間。

因此,我需要在dbo.userActivity的基礎上,根據時間計算以'before','during','after','other'的值附加一列。

我真的不知道如何做到這一點,並希望你能提供任何幫助。

編輯:

好吧,所以我主要是工作。我剛剛看到一些我將要處理的真實數據,並注意到活動時間是完整的日期時間戳,而活動時間表恰好在時間上。所以我需要將日期時間轉換爲我可以比較的東西。

這看起來像它的工作原理:

SELECT * FROM ( SELECT CONVERT(TIME,鈧)作爲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 

對此有何進一步的想法?

回答

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 

你可以這樣獲得的UI與INNER JOIN文本值您TimeStatus參考表

+0

呀,我跑進一個實施它的障礙。見上面的編輯。 –

+0

@AndrewMartin我更新了'CASE'以使用'CAST(ua.Time AS TIME)',它在我進行的簡單測試中起作用。如果遇到任何其他問題,請告訴我。 –

+0

這就是訣竅。比我想要的要簡單得多。再次感謝。 –