Сохранение таблицы БД, отсортированной по многопольной формуле (Microsoft SQL Server) - PullRequest
1 голос
/ 21 марта 2010

У меня есть таблица JOB с двумя интересными столбцами:

  • Дата создания
  • Важность (высокая - 3, средняя 2, низкая - 1).

Приоритет записи JOB рассчитывается так:

Priority = Importance * (time passed since creation)

Проблема в том, что каждый раз, когда я хотел бы выбрать 200 рабочих мест с наивысшим приоритетом, я не хочу прибегать к таблице. Есть ли способ сортировки строк?

Я также думал о том, чтобы иметь три таблицы, одну для High, Medium и Low, а затем отсортировать их по дате создания.

Ответы [ 3 ]

3 голосов
/ 21 марта 2010

Таблицы не "отсортированы";Вы запрашиваете данные на основе своих критериев и добавляете индексы, чтобы помочь в поиске нужных вам порядков.

(Первая ложь: таблицы отсортированы; они хранятся в порядке кластерного индекса.)

Но забудьте о концепции «повторной сортировки» данных.Вставьте свои данные и (с некоторой индексацией) дайте серверу базы данных выполнить свою работу, чтобы вернуть нужные вам данные.

Если вы не получаете нужные данные, возможно, ваш запрос нуждается в дополнительной помощи.

2 голосов
/ 21 марта 2010

Проблема в том, что каждый раз, когда я хотел бы выбрать 200 рабочих мест с наивысшим приоритетом, и я не хочу прибегать к таблице.Есть ли способ сохранить отсортированные строки?

Порядок строк не имеет отношения к базе данных, и не рекомендуется полагаться на недетерминированные вычисления для сортировки.

Предполагая SQL Server 2000+, вы можете использовать этот запрос вместо:

  SELECT TOP 200 t.*
    FROM TABLE t
ORDER BY t.importance * (time passed since creation) DESC
0 голосов
/ 21 марта 2010

Проблема, с которой вы здесь столкнетесь, - это производительность с операцией, которую вы описываете. Движок будет рассчитывать «Значение * (время, прошедшее с момента создания)» для каждой записи в таблице. Это происходит всякий раз, когда у вас есть столбец в функции.

Идея. Для больших таблиц затраты на получение 600 строк и последующее получение 200 верхних из них намного меньше, чем выполнение вычислений для каждого запроса.

SQL не является корректным как есть (порядок и объединения), но идея верна.

SELECT TOP 200 ident
FROM
(
SELECT TOP 200 ident, (GETDATE() - creation_date)  * 1 AS calc_order
FROM jobs
WHERE priority = 1
ORDER BY creation_date
UNION ALL
SELECT TOP 200 ident, (GETDATE() - creation_date)  * 2 AS calc_order
FROM jobs
WHERE priority = 2
ORDER BY creation_date
UNION ALL
SELECT TOP 200 ident, (GETDATE() - creation_date)  * 3 AS calc_order
FROM jobs
WHERE priority = 3
ORDER BY creation_date
) x
ORDER BY
calc_order DESC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...