我的表中有5列:id,x,y,source,distance。
对于每个id,我想找到最近的x& y值并更新距离字段中的值及其在源中的ID。
我可以使用以下查询更新距离:
UPDATE item SET distance = ( SELECT MIN( ABS (a.x - item.x) + ABS (a.y - item.y) )
FROM item AS a WHERE a.id != item.id )
但是我无法更新源代码,因为sqlite不支持从单个选择中进行多列更新。
当我尝试将查询放在where条件中时,我得到错误,没有像item.x这样的列。
UPDATE item SET link = ( SELECT id FROM item AS a WHERE a.id != item.id
ORDER BY ABS (a.x - item.x) + ABS (a.y - item.y) LIMIT 1 )
如何解决我的查询?
答案 0 :(得分:0)
首先,您可以使用以下逻辑获取每条记录的最近ID:
select i.*,
(select id
from item i2
where i2.id <> i.id
order by abs(i2.x - i.x) + abs(i2.y - i.y)
) as closest_id
from item i;
您可以将其放入with
子句中以简化查询的其余部分:
with closest as (
select i.*,
(select id
from item i2
where i2.id <> i.id
order by abs(i2.x - i.x) + abs(i2.y - i.y)
) as closest_id
from item i
)
update item
set link = (select closest_id from closest where closest.id = item.id),
distance = (select abs(i2.x - c.x) + abs(i2.y - c.y)
from closest c join
item i2
on c.closest_id = i2.id
where closest.id = item.id
);
编辑:
如果with
不可用,则可以在没有with
的情况下执行此操作,只需多次使用子查询即可。但是,我建议两个更新:
update item
set link = (select id
from item i2
where i2.id <> item.id
order by abs(i2.x - item.x) + abs(i2.y - item.y)
);
update item
set distance = (select abs(i2.x - item.x) + abs(i2.y - item.y)
from item i2
where i2.id = item.link
);
答案 1 :(得分:0)
显然,SQLite不允许在ORDER BY子句中引用外部表。
您可以通过将距离计算添加到SELECT子句来解决此问题。这需要在其周围包装另一个子查询以仅返回一列:
UPDATE item
SET link = ( SELECT id
FROM ( SELECT id,
ABS (a.x - item.x) + ABS (a.y - item.y)
FROM item AS a
WHERE a.id != item.id
ORDER BY 2
LIMIT 1 ))
如果您先更新link
列,则可以使用该值计算距离,而无需再次搜索整个表格:
UPDATE item
SET distance = ( SELECT ABS (a.x - item.x) + ABS (a.y - item.y)
FROM item AS a
WHERE a.id = item.link )