2013-05-29 3 views
0

У меня есть таблица с дочерним элементом (позиция x, позиция y) и с родителем (позиция x, позиция y) в sql-сервере. Я хочу найти ближайшего родителя для каждого ребенка. Я могу сделать это «плохой путь», но, вероятно, есть решение, не использующее никаких циклов.TOP1 в CROSS JOIN (SQL SERVER)

That`s мой код:

SELECT 
    child.idChild, child.x, child.y, 
    parent.idParent, parent.x, parent.y, 
    sqrt(power(child.x - parent.x, 2) + power(child.y - parent.y, 2)) as distance 
FROM 
    child 
CROSS JOIN 
    parent 
ORDER BY 
    idChild, distance 

Хорошо, That`s хорошо. Но теперь я хочу ограничить родителей только ТОП1 для каждого ребенка.

Благодаря

ответ

1

Удобный способ сделать это с оконными функциями. Чтобы получить верхний ряд, вы можете использовать либо row_number(), либо rank(). Есть разница, когда есть связи. row_number() возвращает только одно из нескольких значений. rank() вернет все из них.

Вот один из способов, чтобы написать запрос:

select idChild, x, y, idParent, parentx, parenty 
from (SELECT child.idChild, child.x, child.y, 
      parent.idParent, parent.x as parentx, parent.y as parenty, 
      ROW_NUMBER() over (partition by child.idchild 
           order by power(child.x - parent.x, 2) + power(child.y - parent.y, 2) 
           ) as seqnum 
     FROM child CROSS JOIN 
      parent 
    ) pc 
where seqnum = 1; 

Я удалил sqrt() от функции расстояния, потому что не нужно при поиске наименьшего числа.