【问题标题】:Need MySQL query for data cleanup需要 MySQL 查询进行数据清理
【发布时间】:2022-01-29 15:33:23
【问题描述】:

我有三张桌子。一张表,有行驶距离

create table routes
(
  slat int,
  slng int,
  dlat int,
  dlng int,
  distance int
);

一个带有站点的表

create table sites
( 
  id int,
  name varchar(100),
  lat int,
  lng int
);

和技术人员的一张桌子

create table fse
(
  id int,
  name varchar(100),
  lat int,
  lng int
); 

行驶距离表是根据 google API 请求动态填写的。所以如果有一个新站点或一个新的技术人员,所有新的旅行距离都由谷歌请求并存储到路由表中

当然也可能发生客户或技术人员离开的情况。在这种情况下,距离表中的条目即使不再使用也会保留在数据库中。

我想删除表中这些未使用的行。所以我正在寻找一个查询,它正在删除站点/fse 表中所有“不存在”的纬度/经度组合,就像在这个小提琴的评论中写的那样

https://www.db-fiddle.com/f/mwF1iyZ7nn8rnDcE8Wstch/0

我可以自己编写此查询,但我唯一的解决方案是使用非常多的子选择。但是我想知道是否没有更有效的方法,希望这里的一位 sql 专业人士可以提供帮助?

【问题讨论】:

    标签: mysql


    【解决方案1】:

    这个查询应该可以工作:

    delete from routes where concat (slat,'|', slng) not in (
      select concat(lat ,'|', lng) from sites 
      union  select concat(lat,'|',lng) from fse
    ) ;
    

    它从表sitesfse 中选择所有记录,并从在子查询中找不到记录的路由中删除行。需要两列的 concat,因为in 只能处理一列。 | 只是用来分隔值

    DB-Fiddle

    【讨论】:

    • MySQL 可以处理元组,因此不需要串联:... (slat, slng) IN (SELECT lat, lng FROM ....
    • DB fiddle 不允许
    • 哦,顺便说一句:不要习惯在字符串或日期文字中使用双引号。是的,遗憾的是 MySQL 和 MariaDB 接受了这一点,但在 SQL 中,双引号通常用于标识符,例如列名。如果您曾经使用过另一个 DBMS(或者未来的 MySQL 或 MariaDB 版本对此更加理智),您可能会收到“无效的对象名称”错误。始终对字符串或日期文字使用单引号。
    • @stickybit,完全同意,而且 MySQL 和 MariaDB 确实会根据 SQL 模式选项改变双引号的含义。因此,即使在当前版本上,使用双引号作为字符串分隔符的代码也可能会在没有警告的情况下中断。
    猜你喜欢
    • 2015-12-20
    • 2014-03-02
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多