我不知道我是否为这个问题选择了合适的标题(如果没有,请相应地更改它)但请考虑我正在使用的以下简化表结构:
----------------------------------------------
| 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)。
我正在尝试选择条件相似的日期;给定一组 i
、j
、k
、x
、y
、z
值 我需要返回按所有值的接近度排序的所有结果作为一个整体 例如,如果 i = 1
、j = 2
、k = 3
、x = 4
、y = 5
和 z = 6
查询应按此顺序返回以下日期:
- 100209
- 100212
- 100210
- 100211
- 100213
我不确定这是否与问题相关,但一些值(i
、j
、k
) 表示越多越好,而其他值(x
、y
、z
)则表示相反:越少越好。
我应该如何构建这样的查询?这可能仅使用 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
---------------------------------------------------------------------------------
我的表结构有更多的列和数千行,但希望这足以让我的观点清晰。我不会像在前面的示例中那样尝试对这些值进行排序,因为我可能会弄错,但我基本上需要对这些数据进行两种类型的查询:
- 显示所有日期,按照我提供的条件的相似度排序
- 显示所有日期,按照日期 X 中观察到的条件的相似性排序
我知道可以使用第一个查询轻松存档第二个查询,但我的问题在于使用多个列按相似性排序,这就是我所说的“按接近度排序”所有值(value)观作为一个整体”。比如,如果我只处理一列,那么按相似度排序会容易得多,但在处理多列时我真的开始头晕目眩了。
目标是能够产生这样的结果:
Today is really similar to d/m/yy, very similar to d/m/yy, somewhat similar to d/m/yy, ...
在我的例子中,我正在处理天气和大气数据,但如果它有帮助,我猜你可以从employee
(有attendance
,hoursPerWeek
和 monthlySalary
列)以及最接近 attendance = 100%
、hoursPerWeek = 40
和 monthlySalary = $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/