2015-05-28 7 views
3

Я создал новый столбец не нуль с значением по умолчанию 0 для моей таблицы и сохраняет порядки отображения. Я хочу обновить все строки для этой таблицы, что displayorder имеет значение row_number() над упорядоченным идентификатором. здесь я могу сделать это для одного id. Как я могу это сделать для всех идентификаторов.Обновление столбца на основе row_number()

мой стол:

id | personid | name | displayorder 
---+----------+--------+------------ 
1 | 10 | test1 | 0 
2 | 10 | test2 | 0 
3 | 10 | test3 | 0 
4 | 10 | test4 | 0 
5 | 10 | test5 | 0 
6 | 11 | test6 | 0 
7 | 11 | test7 | 0 
8 | 12 | test8 | 0 

я хочу результат:

id | personid | name | displayorder 
---+----------+--------+------------ 
1 | 10 | test1 | 1 
2 | 10 | test2 | 2 
3 | 10 | test3 | 3 
4 | 10 | test4 | 4 
5 | 10 | test5 | 5 
6 | 11 | test6 | 1 
7 | 11 | test7 | 2 
8 | 12 | test8 | 1 

здесь мой SQL-код, но он работает только для только один данный ID:

update MyTable 
set displayorder = z.ord 
FROM (
    SELECT row_number() over (order by id) as ord, id 
    FROM MyTable p2 
    where p2.personid = 1 
    ) z 
    where MyTable.id= z.id 
    and personid = 1 
+0

вы действительно есть 2 таблицы - '' productproperty' и MyTable' или это та же таблица? –

+0

Извините, я исправил его. У меня только 1 стол. – Can

+0

, тогда вам определенно лучше пойти с ответом без участия, я думаю, что он будет простейшим и быстрым –

ответ

6

Использовать этот код:

Create TABLE #order 
    (
     Id INT, 
     PersonId INT, 
     Name NVARCHAR(25), 
     DisplayOrder INT 
    ) 

    INSERT INTO #ORDER VALUES(1 , 10 , 'test1',0) 
    INSERT INTO #ORDER VALUES(2 , 10 , 'test2',0) 
    INSERT INTO #ORDER VALUES(3 , 10 , 'test3',0) 
    INSERT INTO #ORDER VALUES(4 , 10 , 'test4',0) 
    INSERT INTO #ORDER VALUES(5 , 10 , 'test5',0) 
    INSERT INTO #ORDER VALUES(6 , 11 , 'test6',0) 
    INSERT INTO #ORDER VALUES(7 , 11 , 'test7',0) 
    INSERT INTO #ORDER VALUES(8 , 12 , 'test8',0) 



update #order 
    Set #order.DisplayOrder=R.DisplayOrder 
    from(select id,ROW_NUMBER() over (partition by S.personid order by S.id) as DisplayOrder 
    from #order S) R 
    where #order.Id=R.id 

    select * from #order 
+0

спасибо, что это сработало. Спасибо, спасибо. – Can

+0

Всегда Добро пожаловать! –

1

Быстрое решение использует ранжирование. Пример должен делать то, о чем вы просили.

DECLARE @Pid TABLE 
(
    Id INT, 
    PersonId INT, 
    Name NVARCHAR(25), 
    DisplayOrder INT 
) 

INSERT INTO @Pid 
VALUES 
(1 , 10 , 'test1',0), 
(2 , 10 , 'test2',0), 
(3 , 10 , 'test3',0), 
(4 , 10 , 'test4',0), 
(5 , 10 , 'test5',0), 
(6 , 11 , 'test6',0), 
(7 , 11 , 'test7',0), 
(8 , 12 , 'test8',0) 

UPDATE pid 
SET DisplayOrder = dpid.rank 
FROM @Pid pid 
INNER JOIN 
(
    SELECT *, Rank() OVER(Partition by PersonId Order by Id) as rank 
    FROM @Pid 
)dpid ON dpid.Id = pid.Id 

SELECT * 
FROM @Pid 
+0

это оригинальный вопрос, есть 2 таблицы, и у вас есть только один. Я на 90% уверен, что там должна быть только одна таблица, но я бы подождал, когда будет сообщение о старте темы. –

+0

Я понял, что если бы OP соединялся по ID, это не имело бы значения, если это одна или две таблицы (я бы надеюсь, нет, но вы никогда не знаете). Оператор update в приведенном выше примере просто должен быть изменен для обновления второй таблицы. – TYY

+0

это тоже сработало, спасибо за вашу помощь. – Can

2

если productproperty и MyTable действительно та же таблица, я бы это сделать:

with cte as (
    select 
     t.displayorder, 
     row_number() over(partition by t.PersonId order by t.Id) as rn 
    from MyTable as t 
) 
update cte set displayorder = rn 

Это один используя тот факт, что общие выражения таблиц рассматриваются как обновляемые представления в SQL Server.

Или даже создайте представление с помощью row_number() в качестве дисплея, поэтому он будет пересчитан автоматически, поэтому вам не нужно обновлять таблицу каждый раз, когда вы добавляете/удаляете строку.