Автоматическое создание заказов на сортировку с помощью SQL UPDATE - PullRequest
8 голосов
/ 04 февраля 2009

Недавно я импортировал около 60 тыс. Записей в таблицу, которая связывает данные одной таблицы с данными другой таблицы. Тем не менее, мой клиент с тех пор попросил добавить порядок сортировки для всех записей 60k. Я надеюсь, что есть хороший чистый способ автоматически генерировать эти порядки сортировки в SQL Update. Готовые данные должны выглядеть примерно так:

item1ID  item2ID  sortOrder
1           123       1
1           12        2
1           45        3
1           22        4
1           456       5
2           5         1
2           234       2
2           56        3

Можно ли это сделать? Любые предложения будут с благодарностью.

- Anne

Ответы [ 3 ]

10 голосов
/ 04 февраля 2009

Вы можете использовать [ROW_NUMBER] [1] и разделить по Item1ID

UPDATE t1
SET t1.SortOrder = t2.SortOrder 
FROM @t t1
INNER JOIN
(SELECT Item1ID, Item2ID, ROW_NUMBER() OVER
    (PARTITION BY Item1ID ORDER BY Item1ID, Item2ID) AS SortOrder
from @t) t2
ON t1.Item1ID = t2.Item1ID 
AND t1.Item2ID = t2.Item2ID
1 голос
/ 04 февраля 2009

Здесь вы затрагиваете что-то фундаментальное в реляционной модели. В целом, в базах данных нет такого понятия, как внутренний порядок. Если вы хотите получить порядок данных при просмотре таблицы, вы должны явно указать этот порядок.

Так что в общем смысле вы просите невозможного. Вы не можете просто UPDATE таблица и получить автоматическое упорядочение любого запроса на него. Но в смысле запрос за запросом вы всегда можете поставить "ORDER BY item1ID, sortOrder" в любой оператор SELECT, который вы применяете к таблице.

В SQL Server 2005 вы можете написать представление и представить его своему клиенту, используя этот старый хак:

SELECT TOP 100 PERCENT
    item1ID, item2ID, sortOrder  -- and all the other columns
FROM YourTable
ORDER BY item1ID, sortOrder;

Существуют способы сделать такой вид обновляемым, но вам нужно исследовать его самостоятельно. Это не так уж сложно сделать.

Если вы никогда не собираетесь вставлять или изменять данные в этой таблице и если вы хотите снова импортировать данные в таблицу, вы можете определить свою таблицу с помощью идентификатора, а затем вставить свои данные в таблицу в соответствующий порядок. Тогда вы всегда будете заказывать по одному столбцу идентификации. Это будет работать, если ваш клиент всегда просматривает данные в программе, которая позволяет сортировать по одному столбцу. (Кстати, никогда не используйте для этой цели функцию IDENTITY . Она не будет работать.)

CREATE TABLE YourTable (
    SingleSortColumn  INT IDENTITY(1,1) NOT NULL,
    ...
);
INSERT INTO YourTable (
    item1ID, item2ID, sortOrder  -- everything except the SingleSortColumn
)
SELECT  -- all your columns
INTO YourTable
FROM yadda yadda yadda
ORDER BY item1ID, sortOrder;

Надеюсь, это полезно. Извините, если я педантичен.

0 голосов
/ 04 февраля 2009

Теоретически можно сказать:

update mytable 
  set sortOrder = row_number() 
     over (partition by item1id order by item1id, item2id) from mytable

Однако, вы получите сообщение об ошибке:

Msg 4108, Level 15, State 1, Line 1
Windowed functions can only appear in the SELECT or ORDER BY clauses.

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

Например:

select 
    item1ID, 
    item2ID, 
    row_number() 
        over (partition by item1id order by item1id, item2id) as sortOrder 
  into #tmp 
  from mytable

update mytable 
  set sortOrder = T.sortOrder 
  FROM 
    mytable M 
    inner join #tmp T 
        on M.item1ID = T.item1ID 
        AND M.item2ID = T.item2ID

drop table #tmp
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...