我正在尝试使用大约 300k 行表中的订单来查找商品价格的第 95 个百分位数(以及最高购买量)。
我已经成功地使用以下代码找到了第 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
诗。这是我的数据库的链接,如果您想使用它进行困惑/测试:https://gofile.io/?c=Ga6ODr
最佳答案
这个查询应该会给你你想要的结果。它按 price
分配一个 ROW_NUMBER
,并计算每个 type_id
和订单类型 (is_buy_order
) 的所有行数CTE,然后选择 MAX
价格作为 购买
价格(对于 is_buy_order = 1
),以及 >= 第 95 行的最低价格百分位作为第 95 个百分位价格。如果第 95 个百分位数中除了最高价格之外没有任何行,则返回第二高价格。类似的逻辑适用于卖出
和95%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
关于mysql - MySQL (MariaDB) 上的第五个百分位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59905423/