I am noob in postgresql and I am trying to create a function to calculate the distances between a specific value and a set of values(records). Here is the table:
CREATE TABLE test
(
id serial NOT NULL,
name text,
values real[]
)
I want to create a function but I can't figure out how to loop every element in values[]
For example, I would like to select the name with the smallest distance. I didn't find any built-in function for this purpose.
I wrote the code in c# of what I am looking for:
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();
First I would change the name of the column you called values to vals. values is a keyword ofcourse you can write "values" in your queries but I would prefer to circumvent that issue by changing the name.
If I understand your question correctly I think it would be enough in your case to create a distance function then use that in a query. Here is the function:
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;
If you want the name of the closest the query is:
SELECT name
FROM test
ORDER BY distance(test.values, ARRAY[12, 13, 13, 121]) DESC
LIMIT 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With