2015-08-16 2 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. Что здесь происходит, что первые вставки кода в таблицу «Пользователи» при регистрации пользователя. Через некоторое время он активирует свою учетную запись, которая сохраняет данные в UserActivation. UserActivation содержит множество столбцов, но я показываю только те, которые я использую. Проблема заключается в том, что мы добавили datetime после этого и до этого времени сотни данных. То, что я пытаюсь сделать, - обновить дату и время UserActivation, как показано ниже:

Пользователь table, user_id: 95678367 является первым. второй - 72876424. Я хочу обновить datetime таблицы UserActivation строк с идентификатором от 1 до 5, потому что id 6 содержит user_id 72876424. Поэтому я хочу обновить datetime строк с 1 по 5 таким образом, чтобы они приходили с шагом в 3 секунды datetime из таблицы пользователя.

пользователя таблица первая строка имеет user_id и DateTime 2015-07-03 02: 02: 29,863, поэтому обновление DateTime строк 1-5 UserActivation (до второй user_id столкновений пользователей) как

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. считать, что DateTime из таблицы Users 2015-07-07 01: 04: 14.436

И начать обновление DateTime из UserActivation таблицы с шагом по три для строк 6-9, как 10-й строки cotains 3 user_id таблицы Users.

Примечание. Я пытаюсь написать сценарий, чтобы я мог прокручивать обе таблицы и проверять один за другим user_id как таблицы, так и обновления соответственно, но я не эксперт в сценариях sql-сервера. Отображение того, как цикл через результат SELECT и обновление в цикле также поможет.

+0

Не можете почитать ваши данные? почему у вас есть user_id столбец в UserActivation, если он не является внешним ключом для пользователей? – 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

Для того, чтобы обновить таблицу, вам нужно заменить ЗЕЬЕСТ с:

/* 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 co SET co.datetime = DATEADD (второй, 3 * (co.id - cap.maxID), co. [datetime]) Вместо SELECT co.id, co.datetime, DATEADD (второй, 3 * (co. 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 
Смежные вопросы