MS SQL SERVER ответ ...
DECLARE
@min_time DATETIME,
@max_time DATETIME,
@min_price MONEY,
@max_price MONEY
SELECT
@min_time = MIN(timestamp),
@max_time = MAX(timestamp),
@min_price = MIN(price),
@max_price = MAX(price)
FROM
yourTable
SELECT
*
FROM
yourTable
ORDER BY
(CAST(DATEDIFF(second, @min_time, timestamp) AS FLOAT) / CAST(DATEDIFF(second, @min_time, @max_time) AS FLOAT)) * @slider
+
(CAST(price - @min_price AS FLOAT) / CAST(@max_price - @min_price AS FLOAT)) * (1 - @slider)
-- Where te slider value is anything between 0 and 1
Чтобы заставить ваши настроения работать, я делаю один и тот же расчет времени и цены - я конвертирую их в значение от 0 до 1 (которое я назову positional weight
).
- 0.0 = равно минимальному значению для этого поля
- 0.5 = точно на полпути между минимальным и максимальным значениями этого поля
- 1,0 = равно максимальному значению для этого поля
Затем я умножаю позиционный вес на значение ползунка (или значение 1) и складываю вместе два результата.
Когда ползунок на 0 или 1, это просто; один позиционный вес умножается на один, один позиционный вес умножается на ноль. Другими словами, один позиционный вес не изменяется, а один позиционный вес игнорируется.
Когда ползунок равен 0,5, половина каждого позиционного веса складывается вместе.
В случае, когда 99,999% значений расположены близко друг к другу и существует один экстремальный выброс, это может привести к тому, что это поле станет необычно доминирующим или наоборот. (Большинство позиционных весов очень близко к 0 или 1)
Таким образом, один из вариантов состоит в том, чтобы основывать позиционный вес только на порядке данных. Таким образом, в случае, когда многие значения близки, но с одним крайним выбросом; значение в середине списка по-прежнему получает 0,5, поскольку это позиционный вес. Короче говоря, важна его позиция в последовательности, а не ее фактическое значение.
DECLARE
@count FLOAT
SELECT
@count = CAST(COUNT(*) AS FLOAT)
FROM
yourTable
WITH
ordered_data
AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY timestamp) AS time_id,
ROW_NUMBER() OVER (ORDER BY price) AS price_id,
*
FROM
yourData
)
SELECT
*
FROM
ordered_data
ORDER BY
(CAST(time_id AS FLOAT) / @count) * @slider
+
(CAST(price_id AS FLOAT) / @count) * (1 - @slider)
Что лучше, почему и т. Д. Начинает получать статистические данные и зависит именно от того, чего вы пытаетесь достичь. Может быть, вы могли бы взять среднее значение двух разных позиционных весов и использовать их? Надеюсь, это даст вам возможность поработать.
Оба ответа заставляют positional weight
быть в процентах. Это потому, что ВРЕМЯ и ЦЕНА могут иметь совершенно разные масштабы. Делая их percantages (от 0 до 1) заставляет их быть одинакового масштаба. Возможно, вы захотите рассмотреть альтернативные механизмы для выбора подходящих шкал, и они могут отличаться для каждого поля.
Каждый ответ определяет позиционный вес относительно фиксированной точки: самого низкого пункта в списке. Вы можете выбрать другие контрольные точки, такие как СРЕДСТВО, РЕЖИМ или МЕДИАНА. При этом у вас будет диапазон позиционных весов (от -x до + y), причем x и y потенциально могут быть очень разными значениями. Затем вы можете изменить их вес (от -1 до +1). Это потребует масштабирования их вдоль кривой, и вам нужно будет решить, как определить эту кривую.
Каждый ответ вырабатывает «расстояние» от фиксированной контрольной точки от 0 до 1 или в предыдущем абзаце от -1 до +1. Это предполагает, что время и цена всегда одинаково важны. Но что, если вы выбрали только дорогие предметы, где позиционный вес всегда должен быть ближе к 1? Вам потребуется механизм для масштабирования по «всем возможным значениям», а не по «всем существующим значениям».
У вас есть большой выбор, и выбор правильного или неправильного зависит от функциональных требований, которые вы изложили. Я не верю, что есть универсальная Истина, которую можно найти. Возможно, вам нужно создать несколько примеров и решить, чего вы хотите достичь, а затем выяснить КАК?