2015-06-09 5 views
0

У меня есть таблицаИзменение значений столбцов на основе другого столбца в одной таблице

+---------------------+ 
| ID | Code | Amount -| 
+---------------------+ 
| 1 | 101 | 1.2  | 
| 1 | 102 | 1.3  | 
| 1 | 103 | 1.3  | 
| 1 | 104 | 1.4  | 
| 1 | 105 | 1.2  | 
| 2 | 101 | 1.5  | 
| 2 | 102 | 1.4  | 
| 2 | 103 | 1.3  | 
| 2 | 104 | 1.1  | 
| 2 | 105 | 1.0  | 
+---------------------+ 

То, что я пытаюсь сделать, это изменить столбец суммы для каждого идентификатора, который не является кодом 101 до значения в размере от код 101

Итак, мой вывод должен быть таким.

+---------------------+ 
| ID | Code | Amount -| 
+---------------------+ 
| 1 | 101 | 1.2  | 
| 1 | 102 | 1.2  | 
| 1 | 103 | 1.2  | 
| 1 | 104 | 1.2  | 
| 1 | 105 | 1.2  | 
| 2 | 101 | 1.5  | 
| 2 | 102 | 1.5  | 
| 2 | 103 | 1.5  | 
| 2 | 104 | 1.5  | 
| 2 | 105 | 1.5  | 
+---------------------+ 

Это явно упрощенная таблица, чтобы показать то, что мне нужно, как количество строк сегодня составляет более 100000, но будет меняться каждый день.

Я попытался использовать курсор, но он очень медленный. Есть какой-либо способ сделать это?

Благодаря

+1

Вы хотите обновить таблицу, или просто настроить нужный результат? – jarlh

+0

Есть два значения для 101. Любая логика? –

+0

@jarlh Извините, если вы сказали это. Я хочу ОБНОВИТЬ таблицу – Sam

ответ

2
update t 
set t.amount = t2.amount 
from your_table t 
join 
(
    select id, min(amount) as amont 
    from your_table 
    where code = 101 
    group by id 
) t2 on t1.id = t2.id 
where t.code <> 101 
-1
Update YourTable 
Set Amount = (select top 1 a.amount from yourtable a where a.id = YourTable.id and a.code = 101) 

EDIT:

Проверить это

select *,(select top 1 a.amount from yourtable a where a.id = YourTable.id and a.code = 101) as [your update value] 
from YourTable 
+0

Ответ вы не помогли. Он просто возвращал сумму одинаково для всех идентификаторов – Sam

+0

Проверьте отредактированный ответ, я забыл добавить псевдоним в подзапрос в инструкции обновления. –

+0

Ненавижу случайные нисходящие –

-1

Используйте подзапрос, чтобы получить 101 сумму для ID:

update tablename t1 set amount = (select max(amount) from tablename t2 
            where t1.ID = t2.id 
            and t2.code = 101) 
where t1.code <> 101; 

Не нужно обновлять 101 строку, не допускать их из транзакции (where t1.code <> 101).

MAX(amount) Необходимо убедиться, что только одна строка вернулась из подзапроса.

+2

Вниз, почему? Если это не сработает, пожалуйста, по крайней мере, скажите мне! – jarlh

+0

Я не проголосовал за вас. Я даже не пробовал ваш код. Ответ, отмеченный как правильный ответ, сработал, он просто оказался тем, кого я попробовал в первую очередь. Но не был ли я, кто проголосовал – Sam

0

Вы можете использовать UPDATE FROM как этот

UPDATE Tbl1 
SET Amount = Tbl2.Amount 
FROM Tbl1 
INNER JOIN 
(
SELECT ID,Code,Amount 
FROM Tbl1 
WHERE Code = 101 
)Tbl2 
ON Tbl1.ID = Tbl2.ID 
WHERE Tbl1.Code <> 101; 

Редактировать

Если может быть несколько значений количества одного и того же кода и ID, GROUP BY может быть использован, как это.

UPDATE Tbl1 
SET Amount = Tbl2.Amount 
FROM Tbl1 
INNER JOIN 
(
SELECT ID,MAX(Amount) as Amount 
FROM Tbl1 
WHERE Code = 101 
GROUP BY ID 
)Tbl2 
ON Tbl1.ID = Tbl2.ID 
WHERE Tbl1.Code <> 101; 
+0

, почему downvote? – ughai

+0

Не уверен, кто был ниспослан, но не был мной. Я даже не пробовал ваш код. Ответ, отмеченный как правильный ответ, сработал, он просто оказался тем, кого я попробовал в первую очередь. Но не был ли кто-то проголосовал – Sam

+0

@Sam - Это прекрасно, чтобы отметить ответ, принятый, если он решил вашу проблему, даже если есть другие доступные решения, которые тоже работают. Не ошибка. Голодание ответа без комментариев бесполезно для человека, который ответил. У него нет возможности улучшить свой ответ, если есть какие-либо проблемы с ним (если проблема не очевидна) – ughai

1

Это будет делать трюк:

DECLARE @t table(ID int, Code int, Amount decimal(6,1)) 

INSERT @t values 
(1,101,1.2),(1,102,1.3), 
(1,103,1.3),(1,104,1.4), 
(1,105,1.2),(2,101,1.5), 
(2,102,1.4),(2,103,1.3), 
(2,104,1.1),(2,105,1.0) 

;WITH CTE AS 
(
    SELECT 
    min(CASE WHEN Code = 101 THEN amount end) 
     over (partition by ID) newAmount, 
    Code, 
    Amount 
    FROM @t 
) 
UPDATE CTE 
SET Amount = newAmount 
WHERE 
    code <> 101 
    AND newAmount is not NULL 


SELECT * FROM @t 

Результат:

ID Code Amount 
1 101 1.2 
1 102 1.2 
1 103 1.2 
1 104 1.2 
1 105 1.2 
2 101 1.5 
2 102 1.5 
2 103 1.5 
2 104 1.5 
2 105 1.5 
Смежные вопросы