Этот запрос должен дать вам результаты, которые вы хотите. Он выделяет ROW_NUMBER
на price
, а также считает все строки для каждого type_id
и типа заказа (is_buy_order
) в CTE, а затем выбирает цену MAX
в качестве цены buy
(для * 1007). *), а минимальная цена для строк> = 95-й процентиль как цена 95-го процентиля. Если в 95-м процентиле нет строк, отличных от самой высокой цены, возвращается вторая по величине цена. Аналогичные логики c применимы к генерации цен sell
и 95th%sell
:
WITH prices AS (
SELECT type_id, price, is_buy_order,
ROW_NUMBER() OVER (PARTITION BY type_id, is_buy_order ORDER BY price DESC) AS rownr,
COUNT(*) OVER (PARTITION BY type_id, is_buy_order) AS num_rows
FROM orderbuffertest
)
SELECT type_id,
MAX(CASE WHEN is_buy_order = 1 THEN price END) AS buy,
COALESCE(MIN(CASE WHEN is_buy_order = 1 AND 100.0 * (rownr - 1) / num_rows <= 5 AND rownr != 1 THEN price END),
MAX(CASE WHEN is_buy_order = 1 AND rownr = 2 THEN price END)) AS `95th%buy`,
MIN(CASE WHEN is_buy_order = 0 THEN price END) AS sell,
COALESCE(MAX(CASE WHEN is_buy_order = 0 AND 100.0 * rownr / num_rows >= 95 AND rownr != num_rows THEN price END),
MAX(CASE WHEN is_buy_order = 0 AND rownr = num_rows - 1 THEN price END)) AS `95th%sell`
FROM prices
GROUP BY type_id
Если вы по какой-то причине не можете использовать CTE, вы можете написать CTE как подзапрос:
SELECT type_id,
MAX(CASE WHEN is_buy_order = 1 THEN price END) AS buy,
COALESCE(MIN(CASE WHEN is_buy_order = 1 AND 100.0 * (rownr - 1) / num_rows <= 5 AND rownr != 1 THEN price END),
MAX(CASE WHEN is_buy_order = 1 AND rownr = 2 THEN price END)) AS `95th%buy`,
MIN(CASE WHEN is_buy_order = 0 THEN price END) AS sell,
COALESCE(MAX(CASE WHEN is_buy_order = 0 AND 100.0 * rownr / num_rows >= 95 AND rownr != num_rows THEN price END),
MAX(CASE WHEN is_buy_order = 0 AND rownr = num_rows - 1 THEN price END)) AS `95th%sell`
FROM (
SELECT type_id, price, is_buy_order,
ROW_NUMBER() OVER (PARTITION BY type_id, is_buy_order ORDER BY price DESC) AS rownr,
COUNT(*) OVER (PARTITION BY type_id, is_buy_order) AS num_rows
FROM orderbuffertest
) prices
GROUP BY type_id
Демонстрация на dbfiddle