2015-08-16 197 views
1

我正在處理2個表格。使用另一個表中的數據更新一個表格

用戶:

+----+----------+-------------------------+ 
| id | user_id | datetime    | 
+----+----------+-------------------------+ 
| 1 | 95678367 | 2015-07-03 02:02:29.863 | 
| 2 | 72876424 | 2015-07-07 01:04:14.436 | 
| 3 | 74293582 | 2015-07-11 10:02:45.523 | 
+----+----------+-------------------------+ 

UserActivation:

+-----+----------+-------------------------+ 
| id | user_id | datetime    | 
+-----+----------+-------------------------+ 
| 1 | 95678367 | 2015-07-03 02:02:29.863 | 
| 2 | 09235892 | 2015-07-03 02:02:29.863 | 
| 3 | 90328574 | 2015-07-03 02:02:29.863 | 
| 4 | 24714287 | 2015-07-03 02:02:29.863 | 
| 5 | 02743723 | 2015-07-03 02:02:29.863 | 
| 6 | 72876424 | 2015-07-07 01:04:14.436 | 
| 7 | 09385732 | 2015-07-07 01:04:14.436 | 
| 8 | 74576234 | 2015-07-07 01:04:14.436 | 
| 9 | 75439273 | 2015-07-07 01:04:14.436 | 
| 10 | 74293582 | 2015-07-11 10:02:45.523 | 
| 11 | 94562872 | 2015-07-11 10:02:45.523 | 
| 12 | 80367456 | 2015-07-11 10:02:45.523 | 
| 13 | 76537924 | 2015-07-11 10:02:45.523 | 
+-----+----------+-------------------------+ 

我使用SQL Server 2012.我想更新表UserActivation的時機。這裏發生了什麼,當用戶註冊時,第一個代碼在Users表中插入數據。過了一段時間後,他激活了他的帳戶,該數據保存在UserActivation中。 UserActivation包含許多列,但我只顯示我正在使用的那些列。問題是我們增加了datetime列,直到那個時候有數百個數據在那裏。我正在嘗試更新UserActivation的日期時間,如下所示:

用戶表中,user_id:95678367是第一個。第二個是72876424.我想更新id爲1到5的行的UserActivation表的日期時間,因爲id 6包含user_id 72876424.所以我想更新第1行到第5行的日期時間,使它們以3秒遞增來自用戶表的日期時間。

用戶表第一行已經user_id說明和日期時間2015年7月3日02:02:29.863,所以更新行UserActivation 1-5的日期時間(直到用戶遇到的第二USER_ID) as

row1 -> **2015-07-03 02:02:31.863** 
row2 -> **2015-07-03 02:02:34.863** 
row3 -> **2015-07-03 02:02:37.863** 
row4 -> **2015-07-03 02:02:40.863** 
row5 -> **2015-07-03 02:02:43.863** 

之後,如果我們從Users表中觸發第二個ID,採取從日期時間用戶表2015年7月7日01:04:14.436

,並開始與對行6-9的第10行cotains用戶表中的第3 user_ID的三個增量UserActivation表的更新日期時間。

注:我正在嘗試編寫一個腳本,以便我可以遍歷這兩個表並逐個檢查兩個表的user_id,並相應地進行更新,但我並不擅長於sql服務器腳本。顯示如何循環通過SELECT結果並在循環中更新也將有所幫助。

+0

你能解釋一下你的數據結構嗎?爲什麼在UserActivation中有一個user_id列,如果它不是用戶的外鍵? – Amit

+0

在這兩個表中是否有任何字段可用於訂購行? – DarkKnight

+0

@Amit user_id是兩個表的外鍵,這裏沒有提到。 – sumit

回答

1

計算「滾動」時間戳的一種方法是使用交叉應用。看到這一點:

WITH cte AS (
SELECT ua.id, ua.[datetime], CASE WHEN u.id IS NULL THEN -1 ELSE 0 END AS gapN 
FROM UserActivation ua LEFT JOIN Users u 
    ON ua.user_id = u.user_id 
) 
SELECT co.id, co.datetime, DATEADD(second, 3*(co.id-cap.maxID), co.[datetime]) newDatetime 
FROM cte co CROSS APPLY (
    SELECT MAX(id) maxID 
    FROM cte ca 
    WHERE ca.id <= co.id AND ca.gapN = 0 
) cap 

你可以看到 「活」 上SQLFiddle

爲了更新表,你需要更換SELECT子句:

/* SAME AS ABOVE UNTIL THE SELECT LINE */ 
UPDATE co 
SET co.datetime = DATEADD(second, 3 * (co.id - cap.maxID), co.[datetime]) 
FROM UserActivation co CROSS APPLY (
/* SAME AS ABOVE AFTER THE FROM LINE */ 
+0

感謝您的回覆...我插入了 UPDATE coSET co.datetime = DATEADD(second,3 *(co.id - cap.maxID),co。[datetime])代替SELECT co.id,co.datetime,DATEADD(second,3 * id-cap.maxID),co。[datetime])newDatetime ...什麼也沒有發生...... – sumit

+1

@sumit,對不起,看到更正。需要使用使用實際表格的FROM,而不是CTE。 – Amit

+0

偉大的是在小提琴工作......但是當我在我的機器上運行它的投擲錯誤...'cte'附近的語法不正確。 – sumit

0

試試這個

update ua 
set ua.datetime = u.datetime 
from users u left join useractivation ua on u.user_id = ua.user_id 

;with cte 
as 
(
    select id,user_id,datetime from useractivation where id=1 
    union all 
    select ua.id,ua.user_id, 
    case when ua.datetime is null then DATEADD(ss,3,c.datetime) else ua.datetime end as datetime 
    from cte c inner join useractivation ua on c.id+1 = ua.id 
) 

update ua 
set ua.datetime = c.datetime 
from cte c inner join useractivation ua on c.id = ua.id 
相關問題