简体   繁体   English

mysql查询以找到最常见的及其相邻的数字

[英]mysql query to find most common and their neighboring numbers

I hope I phrased the question right, I Have been on this for quite sometime now looking for different approaches, I have an app that polls users for prices they think are right for a commodity then from there the app is to come up with an average price based on the most common to near common prices and averaging them issue is coming up with a query that can find those prices, so a sample of my table: 我希望我把这个问题说对了,我已经有一段时间了,现在正在寻找不同的方法,我有一个应用程序可以对用户调查他们认为适合某种商品的价格,然后从那里得出平均价格。基于most common near common prices并对其进行平均的near common prices问题是提出了一个可以找到这些价格的查询,因此我的表格示例:

|id |commodityFk|price |dateCreated        |
--------------------------------------------
|1  |1          |1200  |2016-12-24 22:30:30|
|2  |1          |500000|2016-12-24 22:30:30|
|3  |1          |500000|2016-12-24 22:30:30|
|4  |1          |450000|2016-12-24 22:30:30|
|5  |1          |506980|2016-12-24 23:15:12|
|6  |1          |2000  |2016-12-25 23:57:06|

so from this table the most common price is 500000 but we also have prices like 506980 and 450000 which are near the common price so we expect it to average 500000, 500000, 450000 and 506980 personally I am not conversant with MySQL any help solving this will be appreciated. 因此,从该表中most common price500000但我们也有像506980450000这样的价格,它们都near the common price因此我们个人期望它的平均near the common price500000, 500000, 450000 and 506980不胜感激。

Are you looking for an entirely MySQL based solution? 您是否正在寻找完全基于MySQL的解决方案? As mentioned in a comment, you should really define "near" more explicitly. 如评论中所述,您应该真正更明确地定义“ near”。 In the below example, I've called any value within 1 Std Deviation of the average a "near" value. 在下面的示例中,我将平均值的1个标准偏差内的任何值称为“接近”值。

Additionally, what do you do if there is more than 1 most common price? 此外,如果最常见的价格超过1,该怎么办? Without knowing the specifics of your requirements I might suggest taking an approach that bypasses that problem entirely by using the average as a starting point rather than the mode. 在不了解您的需求细节的情况下,我可能会建议采取一种方法,将平均值作为起点而不是模式,从而完全绕开该问题。 Alternatively, you could use a COALESCE() function to attempt to get a mode and then use the average if that fails. 或者,您可以使用COALESCE()函数尝试获取模式,然后在失败的情况下使用平均值。

Here is an example of something that will output a value based on the clustering of values and avoids having to deal with weird mode related edge cases. 这是一些示例,这些示例将基于值的聚类输出一个值,并且避免处理与怪异模式相关的边缘情况。

SELECT AVG(price) FROM prices
  JOIN (SELECT AVG(price) as rawAverage, STD(price) as deviation FROM prices) stats
  WHERE commodityFk = 1
  AND price BETWEEN 
    (rawAverage - deviation) AND (rawAverage + deviation);

This is obviously just a starting point but it is fairly scalable. 显然,这只是一个起点,但它具有相当的可扩展性。 You could easily change the expression in the JOIN clause to change how the boundaries of "near" values are defined. 您可以轻松地更改JOIN子句中的表达式以更改“近”值的边界的定义方式。

You might find it helpful to return the full price list from SQL and create a PHP function that analyzes the list of prices to determine the "prices near the common price". 您可能会发现,从SQL返回完整的价格列表并创建一个PHP函数来分析价格列表以确定“接近公共价格的价格”会很有帮助。

This would make it easy to tweak the criteria. 这将使调整标准变得容易。

Perhaps something like this would be a start for you: 也许这样的事情可能是您的起点:

function findPricesNearCommonPrice($data)
{
    $pricesNearCommonPrice = Array();

    // find most common price
    $countOfEachValue = array_count_values($data);
    $mostCommonPrice = array_search(max($countOfEachValue), $countOfEachValue); // doesn't account for items that occur the same number of times, but you could make it do that :-)
    echo "Most Common Price: " . $mostCommonPrice . "<br><br>";

    $tolerance = .15; // 15%

    $minNearPrice = $mostCommonPrice * (1 - $tolerance);
    $maxNearPrice = $mostCommonPrice * (1 + $tolerance);

    foreach ($data as $p) {
        if ($p > $minNearPrice && $p < $maxNearPrice) {
            $pricesNearCommonPrice[] = $p;
        }
    }

    return $pricesNearCommonPrice;
}

Then if you do: 然后,如果您这样做:

$data = Array(500000, 500000, 450000, 506980, 2000);

$values = findPricesNearCommonPrice($data);
$average = array_sum($values) / count($values);

echo "Prices near the most common price:<br>";
echo implode(", ",$values);

echo "<br><br>";
echo "Average: " . $average;

You get: 你得到:

Most Common Price: 500000

Prices near the most common price:
500000, 500000, 450000, 506980

Average: 489245

Of course you'll need to modify it to fit your exact needs and format of your data, but hopefully it's a start. 当然,您需要对其进行修改以适合您的确切需求和数据格式,但是希望这是一个开始。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM