postgresql创建函数欧几里德距离n维

时间:2015-12-14 16:54:33

标签: postgresql

我是postgresql中的noob,我正在尝试创建一个函数来计算特定值和一组值(记录)之间的距离。这是表格:

CREATE TABLE test
(
  id serial NOT NULL,
  name text,
  values real[]
)   

我想创建一个函数,但我无法弄清楚如何循环值[]

中的每个元素

例如,我想选择距离最小的名称。我没有为此目的找到任何内置函数。

我在c#中编写了我正在寻找的代码:

List<double> res = new List<double>();
List<double[]> listDataBase=new List<double[]>();
double[] query = new double[] {12, 13, 13, 121};

double[] b = new double[] { 121, 1, 12, 124 };
double[] c = new double[] { 123, 123, 15, 122 };
double[] d = new double[] { 121, 1, 12, 124 };
double[] e = new double[] { 123, 123, 15, 122 };
listDataBase.Add(b);
listDataBase.Add(c);
listDataBase.Add(d);
listDataBase.Add(e);
foreach (double[] k  in listDataBase)
{
    double sum = 0;
    for (int i = 0; i < query.Length; i++)
    {
        sum += Math.Pow(query[i] - k[i], 2);
    }
    res.Add(Math.Sqrt(sum));
}

res.Sort();

1 个答案:

答案 0 :(得分:2)

首先,我将您调用值的列的名称更改为val。值是一个关键字,您可以在查询中写入“值”,但我更愿意通过更改名称来规避该问题。

如果我正确理解你的问题,我认为在你的情况下创建一个距离函数就足够了,然后在查询中使用它。这是功能:

CREATE OR REPLACE FUNCTION distance(l real[], r real[]) RETURNS real AS $$
DECLARE
  s real;
BEGIN
  s := 0;
  FOR i IN 1..4 LOOP
    s := s + ((l[i] - r[i]) * (l[i] - r[i]));
  END LOOP;
  RETURN |/ s;
END;
$$ LANGUAGE plpgsql;

如果您想要最接近查询的名称是:

SELECT name
FROM test
ORDER BY distance(test.values, ARRAY[12, 13, 13, 121]) DESC
LIMIT 1