Xpoint
   [напомнить пароль]

Алгоритм вычисления рейтига(вычисление единого числа отражающего положение записи в списке)

Метки: [без меток]
2012-07-02 21:29:42 [обр] OlgaV+[досье]

Имеется последовательность чисел различных типов: дробные, целые, булевские (выриация целых можно сказать: 0, 1). Количество чисел в последовательни всегда одинаково. Последовательность используется для сортировки записей, последовательность чисел - есть сортируемые атрибуты. требуется получить единое число отражающее позицию в отсортированном списке.

Если перевести на язык реляционных баз данных, получаем таблицу (см. изображение с отфотматированой версией):

t_apartment
address, price(a), maintenance_fee(b), property_tax(c), has_parking(d), has_storage(e), area(f),
4-3000 Finch $240,000 $340 $1,450 1 0 700
45-456 Yonge $210,000 $230 $1,220 0 1 580
7-898 Bloor $170,000 $167 $1,100 1 0 679

SQL запрос выглядит так:
SELECT * FROM t_apartment ORDER BY price DESC, maintenance_fee DESC, property_tax DESC, has_parking DESC, has_storage DESC, area DESC;

требуется добавить числовое поле (ranking) отражающее значения в последовательности для каждой строки, таким образом запрос может быть упрощен:

SELECT * FROM t_apartment ORDER BY ranking [DESC];

Другими словами, ищу алгоритм получения значмении для поля ranking

Заранее спасибо за предложения решений!

спустя 13 часов [обр] Lynn «Кофеман»(0/571)[досье]
сообщение промодерировано

Учитывая что это число не является абсолютным, а зависит от всех остальных элементов в таблице, ничего сильно умнее приведённого вами SELECT'а с последующей простановкой поля ranking придумать не удастся. Да ещё и любое изменение любого поля в таблице будет требовать пересчёта этого поля.

В чём заключается реальная задача?

спустя 6 часов [обр] OlgaV+[досье]
рельная задача собственго и заключается в упрощении запроса и ускорении сортировки выборки.
главное получить число ranking не путем присвоения порядкового значения относительно текущей выброки, а подобрать алгоритм отображения множества чисел и их последовательности в постоянное значение - независимо от прибывающих и убывающиъ записей в выборки (т. о. не придется переопределять число ranking при добавлении записей)
пока мысли только тупо генерировать строку из чисел с фиксированными позициями для каждого составляющего поля и потом конвертировать ее в integer...
есть надежда на более элегантное решение однако:)
спустя 1 час 36 минут [обр] Евгений Седов aka KPbIC(0/176)[досье]
сообщение промодерировано

Числовая система с каким основанием вас бы устроила применительно к реальным данным?

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

спустя 1 час 19 минут [обр] OlgaV+[досье]
10 было бы оптимально. индексы имеются. запрос простой - записей много - миллионы, и много записей с одинаковыми параметрами - небольшое значение Cardinality.
спустя 12 минут [обр] OlgaV+[досье]
вычисления можно(может и нужно) бизировать на двоичной системе (64bit)
спустя 4 часа 39 минут [обр] Евгений Седов aka KPbIC(0/176)[досье]
сообщение промодерировано

Представьте себе битовую строку, в которой для каждого поля выделен свой диапазон.

Только еще учесть единицы измерения и, например, вместо 240 тысяч принимать 240.

спустя 21 час [обр] Филипп Ткачев(0/112)[досье]
Построить составной индекс по всем полям выборки в той же последовательности, что и в запросе. Должно работать быстро.
спустя 18 минут [обр] Филипп Ткачев(0/112)[досье]

По-хорошему, можно поступить так:

SELECT price FROM t_apartment GROUP BY price

Получить ряд, который пронумеровать. Каждый номер, это значение вашего нового индекса для выбранного ряда данных (price).
Определить ширину индекса в байтах через максимальное значение индекса. Это
Пройтись так по каждой записи, построить временные таблицы индексов, потом опираясь на них, построить свое поле ranking используя битовые операции и операции сдвига.
Построить по полю ranking новый индекс.
На самом деле это относительно тяжелая операция для таблицы в миллионы записей, но при интенсивных выборках это окупится простотой решения. Главное, что при обновлении базы наверняка можно использовать низкоприоритетные фоновые UPDATE. Можно также применить триггеры AfterInsert и если предварительно позаботиться о ширине поля под индексы рядов, то можно перестраивать лишь измененные участки данных используя битовые операции.

Powered by POEM™ Engine Copyright © 2002-2005