在MySQL中使用MEDIAN和MAX,MIN和AVG功能

jef*_*ind 7 mysql sql statistics median

我有以下MySQL查询,它完美地工作:

select 
    count(*) as `# of Data points`, 
    name, 
    max((QNTY_Sell/QNTYDelivered)*1000) as `MAX Thousand Price`,
    min((QNTY_Sell/QNTYDelivered)*1000) as `MIN Thousand Price`,
    avg((QNTY_Sell/QNTYDelivered)*1000) as `MEAN Thousand Price` 
from 
    table_name 
where 
    year(date) >= 2012 and 
    name like "%the_name%" and 
    QNTYDelivered > 0 and 
    QNTY_Sell > 0 
group by name 
order by name;
Run Code Online (Sandbox Code Playgroud)

现在我还想添加一个结果列,它为每行提供MEDIAN数据.在SELECT这个完美的世界中,这将是这样的:

median((QNTY_Sell/QNTYDelivered)*1000) as `MEDIAN Thousand Price`
Run Code Online (Sandbox Code Playgroud)

在Google上搜索MySQL中值函数让我得到了这个答案,如果您对整个表的数据集的中位数感兴趣,这似乎没问题: 使用MySQL计算中值的简单方法

这里的不同之处在于我按name列对表格中的数据进行分组,并希望获得按此列分组的每行数据的中位数.

有谁知道允许我这样做的好玩法?

谢谢!

Ser*_*ton 3

我发现做到这一点的唯一方法是通过字符串操作:
创建GROUP_CONCAT所有值的列表,然后使用缩进SUBSTRING_INDEX获取中值

SELECT
    count(*) AS `# of Data points`,
    name,
    max((QNTY_Sell/QNTYDelivered)*1000) AS `MAX Thousand Price`,
    min((QNTY_Sell/QNTYDelivered)*1000) AS `MIN Thousand Price`,
    avg((QNTY_Sell/QNTYDelivered)*1000) AS `MEAN Thousand Price`
  , CASE (count(*) % 2)
    WHEN 1 THEN SUBSTRING_INDEX(
      SUBSTRING_INDEX(
        group_concat((QNTY_Sell/QNTYDelivered)*1000 
                      ORDER BY (QNTY_Sell/QNTYDelivered)*1000 SEPARATOR ',')
      , ',', (count(*) + 1) / 2)
    , ',', -1)
    ELSE (SUBSTRING_INDEX(
      SUBSTRING_INDEX(
        group_concat((QNTY_Sell/QNTYDelivered)*1000 
                      ORDER BY (QNTY_Sell/QNTYDelivered)*1000 SEPARATOR ',')
      , ',', count(*) / 2)
    , ',', -1)
  + SUBSTRING_INDEX(
      SUBSTRING_INDEX(
        group_concat((QNTY_Sell/QNTYDelivered)*1000 
                      ORDER BY (QNTY_Sell/QNTYDelivered)*1000 SEPARATOR ',')
      , ',', (count(*) + 1) / 2)
    , ',', -1)) / 2
    END median
FROM
    sales
WHERE
    year(date) >= 2012 AND
    name LIKE "%art.%" AND
    QNTYDelivered > 0 AND
    QNTY_Sell > 0
GROUP BY name
ORDER BY name;  
Run Code Online (Sandbox Code Playgroud)

CASE 需要检查我们是否有一个具有奇数个值的中值,或者具有偶数个值的两个中值,在第二种情况下,中值是所找到的两个值的平均值。

SQLFiddle