Sqlite更新列

时间:2015-02-14 11:14:55

标签: sql sqlite android-sqlite

我的表中有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 )

如何解决我的查询?

2 个答案:

答案 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 )