php - 多列整数排序

标签 php sql mysql math sqlite

我不知道我是否为这个问题选择了合适的标题(如果没有,请相应地更改它)但请考虑我正在使用的以下简化表结构:

----------------------------------------------
|  date  |  i  |  j  |  k  |  x  |  y  |  z  |
----------------------------------------------
| 100209 |  1  |  2  |  3  |  4  |  5  |  6  |
----------------------------------------------
| 100210 |  2  |  3  |  4  |  5  |  6  |  7  |
----------------------------------------------
| 100211 |  0  |  1  |  2  |  3  |  4  |  5  |
----------------------------------------------
| 100212 |  1  |  2  |  3  |  4  |  5  |  6  |
----------------------------------------------
| 100213 |  6  |  5  |  4  |  3  |  2  |  1  |
----------------------------------------------

i, j, k, x, y, >z 都是不相关的整数/ float ,它们都代表不同的因素并且可以有非常不同的数量级(i 可以在 1 - 10 之间,而 j 的范围为 100 - 1000)。

我正在尝试选择条件相似的日期;给定一组 ijkxyz 值 我需要返回按所有值的接近度排序的所有结果作为一个整体 例如,如果 i = 1j = 2k = 3x = 4y = 5z = 6 查询应按此顺序返回以下日期:

  1. 100209
  2. 100212
  3. 100210
  4. 100211
  5. 100213

我不确定这是否与问题相关,但一些值(ijk) 表示越多越好,而其他值(xyz)则表示相反:越少越好

我应该如何构建这样的查询?这可能仅使用 SQL 吗?


@奔腾10:

我会尽力回答您的评论。这是我的数据示例:

---------------------------------------------------------------------------------
  date  |  temperature  |  humidity  |  pressure  |  windSpeed  |  moonDistance  
---------------------------------------------------------------------------------
 090206 |  7            |  87        |  998.8     |  3          |  363953        
---------------------------------------------------------------------------------
 ...... |  ...          |  ...       |  ....      |  ...        |  ......        
---------------------------------------------------------------------------------
 100206 |  10           |  86        |  1024      |  2          |  386342        
---------------------------------------------------------------------------------
 100207 |  9            |  90        |  1015      |  1          |  391750        
---------------------------------------------------------------------------------
 100208 |  13           |  90        |  1005      |  2          |  396392        
---------------------------------------------------------------------------------
 100209 |  12           |  89        |  1008      |  2          |  400157        
---------------------------------------------------------------------------------
 100210 |  11           |  92        |  1007      |  3          |  403012        
---------------------------------------------------------------------------------
 100211 |  6            |  86        |  1012      |  2          |  404984        
---------------------------------------------------------------------------------
 100212 |  6            |  61        |  1010      |  3          |  406135        
---------------------------------------------------------------------------------
 100213 |  7            |  57        |  1010      |  2          |  406542        
---------------------------------------------------------------------------------

我的表结构有更多的列和数千行,但希望这足以让我的观点清晰。我不会像在前面的示例中那样尝试对这些值进行排序,因为我可能会弄错,但我基本上需要对这些数据进行两种类型的查询:

  1. 显示所有日期,按照我提供的条件的相似度排序
  2. 显示所有日期,按照日期 X 中观察到的条件的相似性排序

我知道可以使用第一个查询轻松存档第二个查询,但我的问题在于使用多个列按相似性排序,这就是我所说的“接近度排序”所有值(value)观作为一个整体”。比如,如果我只处理一列,那么按相似度排序会容易得多,但在处理多列时我真的开始头晕目眩了。

目标是能够产生这样的结果:

Today is really similar to d/m/yy, very similar to d/m/yy, somewhat similar to d/m/yy, ...

在我的例子中,我正在处理天气和大气数据,但如果它有帮助,我猜你可以从employee(有attendancehoursPerWeekmonthlySalary 列)以及最接近 attendance = 100%hoursPerWeek = 40monthlySalary = $5000,例如。

PS: 既然我已经给出了这个员工示例,我真的不再确定它是否可以与天气示例进行比较我是工作,因为你可以使用 employees 表计算(例如 rating = monthlySalary/hoursPerWeek * attendance)并对列进行加权,但我认为天气表不能做同样的事情- 不管怎样,我们都会感谢您的意见

PS2:我不确定我是否表达得足够好,如果您仍有疑问,请告诉我。 p>


Bounty

Some good suggestions so far, however none of them truly solve my problem. I'm setting up a bounty to hopefully gather even more possible solutions to this problem. Thanks.

最佳答案

您似乎遇到的问题是每列都有不同的比例,因此您不能轻松地将它们组合起来。这个问题可以使用一种称为白化的技术来解决。这涉及计算每列的平均值和标准偏差(您可以在 1 个 SQL 语句中执行此操作),然后在选择时将每列重新缩放为此:

colSortPos = (colValue-colMean) / colStdev

这样做会给你每列在 0 左右的范围内,在 +/- 1 范围内有 +/- 1 个标准差。然后的诀窍是将这些组合起来,以便相似的日期在一起。这里的问题是这不是二维问题,因此您需要多维思考。所以我的建议是将欧氏距离作为排序顺序。

SELECT
    date,
    i,
    j,
    k,
    SQRT( POW((i-@iMean)/@iStdDEv, 2) + POW((j-@jMean)/@jStdDEv, 2) + POW((k-@kMean)/@kStdDEv, 2) )
AS
    sort_order
FROM
    table
ORDER BY
    sort_order

唯一的问题是它将您的问题转换到一维空间,这可能会让您错过一些相关性。为了解决这个问题,我建议使用像 K-means 这样的聚类技术,它实现起来非常简单,而且速度非常快。这将允许您将日期分组到显示最相似性的 k 个集群中 [ http://en.wikipedia.org/wiki/K-means_clustering ].如果您有原始数据并想尝试使用这些(和其他)技术,那么我建议您尝试使用 weka 工具包 [ http://www.cs.waikato.ac.nz/ml/weka/ ] 这将让您尝试使用这些技术。

关于php - 多列整数排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2257304/

相关文章:

mysql - 使用 Union 替代方案按日期从两个表中排序

mysql - 使用各方扮演的各种角色来实现 'party model' 的正确方法是什么?

php - MySQL 表更新错误

php - 提取 1 周时间间隔的记录,并在新的一周开始时启动下一个计时器

PHP 图像上传可以在本地主机上运行,​​但不能在服务器上运行

mysql - 间接路由的 GTFS SQL 查询

MySQL:如何用特殊字符替换文字\r\n\r\n

php - 我是否正确查询 MySQL 表?

javascript - 自动编号?

php - MySQL数据库同步