MySQL 的第 5 个百分位数 (MariaDB)
5th percentile on MySQL (MariaDB)
我正在尝试使用我的 ~300k 行中的订单找到商品价格的第 95 个百分位(和最高购买)table。
我已经成功找到第 95 个百分位和使用此代码的单个项目的最高购买量:
SELECT type_id,
Max(price) AS buy,
Min(price) AS '95th% buy'
FROM (SELECT *,
( Row_number()
OVER (
partition BY type_id
ORDER BY price DESC) ) AS rownr
FROM orderbuffertest AS rownr
WHERE is_buy_order = 1
ORDER BY ( Row_number()
OVER (
partition BY type_id
ORDER BY price DESC) ) ASC) AS t1
WHERE t1.type_id = 44992
AND t1.rownr < (SELECT Count(*)
FROM orderbuffertest
WHERE is_buy_order = 1
AND type_id = 44992) * 0.05;
但是,现在我正在尝试 GROUP BY type_id
,但它打乱了我所有的价值观。
有人知道如何 GROUP BY type_id
这个查询吗?甚至改进原始版本的方法?
提前谢谢你,
TheJozzle
Ps。这是我的数据库的 link,如果您想 mess/test 使用它:https://gofile.io/?c=Ga6ODr
此查询应该会为您提供所需的结果。它通过 price
分配 ROW_NUMBER
并计算 CTE 中每个 type_id
和订单类型 (is_buy_order
) 的所有行,然后选择 MAX
价格作为 buy
价格(对于 is_buy_order = 1
),行的最低价格 >= 第 95 个百分位作为第 95 个百分位价格。如果第 95 个百分位数中除最高价格外没有其他行,则返回第二高的价格。类似的逻辑适用于 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
我正在尝试使用我的 ~300k 行中的订单找到商品价格的第 95 个百分位(和最高购买)table。
我已经成功找到第 95 个百分位和使用此代码的单个项目的最高购买量:
SELECT type_id,
Max(price) AS buy,
Min(price) AS '95th% buy'
FROM (SELECT *,
( Row_number()
OVER (
partition BY type_id
ORDER BY price DESC) ) AS rownr
FROM orderbuffertest AS rownr
WHERE is_buy_order = 1
ORDER BY ( Row_number()
OVER (
partition BY type_id
ORDER BY price DESC) ) ASC) AS t1
WHERE t1.type_id = 44992
AND t1.rownr < (SELECT Count(*)
FROM orderbuffertest
WHERE is_buy_order = 1
AND type_id = 44992) * 0.05;
但是,现在我正在尝试 GROUP BY type_id
,但它打乱了我所有的价值观。
有人知道如何 GROUP BY type_id
这个查询吗?甚至改进原始版本的方法?
提前谢谢你,
TheJozzle
Ps。这是我的数据库的 link,如果您想 mess/test 使用它:https://gofile.io/?c=Ga6ODr
此查询应该会为您提供所需的结果。它通过 price
分配 ROW_NUMBER
并计算 CTE 中每个 type_id
和订单类型 (is_buy_order
) 的所有行,然后选择 MAX
价格作为 buy
价格(对于 is_buy_order = 1
),行的最低价格 >= 第 95 个百分位作为第 95 个百分位价格。如果第 95 个百分位数中除最高价格外没有其他行,则返回第二高的价格。类似的逻辑适用于 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