MySQL 清除表中的重复条目并重新链接依赖表中的 FK

2024-04-23

这是我的情况:我有 2 张桌子,patient and study.

每个表都有自己的 PK,使用自动增量。

就我而言,pat_id 应该是唯一的。它没有在数据库级别声明为唯一,因为它在某些用途中可能不是唯一的(它不是自制系统)。我找到了如何配置系统以将 pat_id 视为唯一,但是我现在需要清理重复患者的数据库并将研究表中的重复患者重新链接到剩余的唯一患者,然后删除重复的患者。

Patient table:

CREATE TABLE `patient` (
  `pk` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `pat_id` VARCHAR(250) COLLATE latin1_bin DEFAULT NULL,
...
  `pat_name` VARCHAR(250) COLLATE latin1_bin DEFAULT NULL,
...
  `pat_custom1` VARCHAR(250) COLLATE latin1_bin DEFAULT NULL
....
  PRIMARY KEY (`pk`)
)ENGINE=InnoDB;

学习表:

CREATE TABLE `study` (
  `pk` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `patient_fk` BIGINT(20) DEFAULT NULL,
...
  PRIMARY KEY (`pk`),
...
  CONSTRAINT `patient_fk` FOREIGN KEY (`patient_fk`) REFERENCES `patient` (`pk`)
)ENGINE=InnoDB;

我发现了一些类似的问题,但不完全相同的问题,特别是它缺少外键与剩余独特患者的链接。

重复条目的清理更新 https://stackoverflow.com/questions/24433306/cleanup-update-for-duplicate-entries

仅更新 MySQL 中重复条目的第一条记录 https://stackoverflow.com/questions/7620038/update-only-first-record-from-duplicate-entries-in-mysql


我就是这样做的。

我重用了一个未使用的字段patient用于标记非重复 (N)、第一个重复 (X) 和其他重复患者 (Y) 的表。您还可以为此添加一列(并在使用后将其删除)。

以下是我清理数据库所遵循的步骤:

/*1: List duplicated */
select pk,pat_id, t.`pat_id_issuer`, t.`pat_name`, t.pat_custom1
from patient t
where pat_id in (
select pat_id from (
select pat_id, count(*)
from patient 
group by 1
having count(*)>1
) xxx);    

/*2: Delete orphan patients */
delete from patient where pk not in (select patient_fk from study);

/*3: Reset flag for duplicated (or not) patients*/
update patient t set t.`pat_custom1`='N';

/*4: Mark all duplicated */
update patient t set t.`pat_custom1`='Y' 
where pat_id in (
select pat_id from (
select pat_id, count(*)
from patient 
group by 1
having count(*)>1
) xxx) ;

/*5: Unmark the 1st of the duplicated*/
update patient t 
join (select pk from (
select min(pk) as pk, pat_id from patient 
where  pat_custom1='Y'  
group by pat_id
) xxx ) x
on (x.pk=t.pk)
set t.`pat_custom1`='X' 
where  pat_custom1='Y'
  ;

/*6: Verify update is correct*/
select pk, pat_id,pat_custom1  
from `patient` 
where  pat_custom1!='N'
order by pat_id, pat_custom1;

/*7: Verify studies linked to duplicated patient */
select p.* from study s
join patient p on (p.pk=s.patient_fk)
where p.pat_custom1='Y';

/*8: Relink duplicated patients */
update study s
join patient p on (p.pk=s.patient_fk)
set patient_fk = (select pk from patient pp
where pp.pat_id=p.pat_id and pp.pat_custom1='X')
where p.pat_custom1='Y';

/*9: Delete newly orphan patients */
delete from patient where pk not in (select patient_fk from study);

/* 10: reset flag */
update patient t set t.`pat_custom1`=null;

/* 11: Commit changes */
commit;

当然有一种更短的方法,使用一些更智能(复杂?)的 SQL,但我个人更喜欢简单的方法。这也让我可以检查每一步是否符合我的预期。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL 清除表中的重复条目并重新链接依赖表中的 FK 的相关文章

  • 如何让 mysql 输出 DateTime 到儒略日数?

    基本上我正在使用用于 Ruby 的 MySQL gem http www tmtm org en mysql ruby 并且我对日期比较没有合理的支持 这Mysql Time类只为我提供了访问器方法 如年 月 秒等 如果我可以将其转换为 R
  • 我想使用 Sequelize 将 MySQL 中的对象数组存储在单个列中

    之前我正在寻找如何使用 Sequelize 在 MySQL 中插入对象数组 然后我找到了一种直接插入数组的解决方案 例如 1 2 在单列中 insert into TABLE NAME id marks VALUES 21 1 2 但我正在
  • 使用 PHP 查询更改表,列名未显示在 phpMyAdmin 中

    这是我的第一篇文章 这里有一篇类似的文章 phpMyAdmin 不显示添加的列 代码日志 https stackoverflow com questions 12960302 phpmyadmin doesnt show added col
  • 如何使用Python高效地将CSV文件数据插入MYSQL?

    我有一个带有 aprox 的 CSV 输入文件 400 万条记录 插入已运行超过 2 小时 但仍未完成 数据库仍然是空的 关于如何实际插入值的任何建议 使用insert into 并且更快 比如将插入物分成块 我对 python 还很陌生
  • MySQL:如何获取上次更新的更改

    我正在使用 MySQL 和 PHP 开发数据库应用程序 此时我正在尝试获取上次更新引起的更改 我解决问题的第一个方法是 使用 SELECT 获取 旧 状态 使用 UPDATE 进行更改 使用 SELECT 获取 新 状态 将数组与 php
  • 选择早于的时间戳

    我如何从数据库中选择超过 12 小时的项目 我使用时间戳列来存储时间 但我认为我不需要年 月 日 只需要小时 我有类似的东西 但它不起作用 没有错误 只是从表中返回所有数据 sql SELECT FROM Y WHERE X and tim
  • 是否可以从数据库转储生成 knex 种子文件?

    就我而言 我使用的是 mysql 但是 我正在寻找一种通用解决方案 用于从当前运行的数据库或数据库转储生成 knex 种子文件 我可以就像是 https github com tgriesser knex issues 944 issuec
  • 按 A 列删除重复项,保留 B 列中具有最高值的行

    我有一个数据框 A 列中有重复值 我想删除重复项 保留 B 列中具有最高值的行 So this A B 1 10 1 20 2 30 2 40 3 10 应该变成这样 A B 1 20 2 40 3 10 我猜想可能有一种简单的方法可以做到
  • 如何将从 MySQL 获取的数据以 JSON 形式返回到 php 文件中?

    我必须将从 MySQL 表中获取的数据作为 JSON 返回到 php 文件中 这是我连接到 mysql 并从中获取数据的代码 现在我怎么能将它作为 JSON 返回呢
  • Mysql 连接到服务器:用户 root@localhost 的访问被拒绝

    edit9 是否有可能我只是缺少文件夹的一些权限 我真的非常非常感谢更多的建议 edit3 由于这篇文章没有得到足够的回复 而且这绝对是至关重要的 我尽快完成这件事 我重建了我的帖子以显示我认为到目前为止我已经扣除的内容 注意 通过许多不同
  • 在 while 循环内查询可以吗?

    我在一个数据库中有两个表 我正在查询第一个表限制 10 然后循环结果 在 while 循环内 我使用第一个查询中的数据作为参数再次执行另一个查询 以下是该脚本的示例
  • 我可以让 MySQL 数据库在插入语句后自动为列分配值吗?

    给定一个具有 ID pk 和 name 列的员工表 ID name 1 John 2 James 3 Tom Can I do INSERT INTO employee name VALUES Jack 并以某种方式让数据库自动分配下一个可
  • 如何通过单个mysql查询更新多个表?

    我有两个表 tb1 和 tb2 我必须在用户级别更新两个表的公共列 我对两个表都有一个共同的标准 例如用户名 所以我想这样更新 UPDATE tb1 tb2 SET user level 1 WHERE username Mr X 但不知何
  • 使用 LIKE 和撇号的 Mysql 查询问题

    所以我有一个有趣的问题 我从未遇到过 并且似乎找不到太多有关纠正该问题的信息 我有一个庞大的数据库 里面有大量的数据 相当于 10 年的数据 并试图对其进行搜索 现在搜索功能运行良好 但最近有人让我注意到一个 错误 如果你愿意的话 我尝试对
  • _mysql_connector.MySQLInterfaceError:命令不同步;您现在无法运行此命令 python msql.connector

    我有一个功能 您可以在下面看到 如果运行此函数 我将收到您在标题中看到的错误 您能帮助我吗 不久前我能够用锁解决这个问题 但现在它们不起作用 我知道这与我的连接有关 但我不知道如何解决这个问题 def insertNewValues sel
  • 计算表中的行数

    获取 MySQL 数据库中特定表的总行数的语法是什么 我一直都这么做 SELECT count FROM table 上面将为您提供所有行的总数 您可以轻松添加 WHERE 子句来获取某个子集的计数 SELECT count FROM ta
  • Mysql:计算访问频率

    我有这张桌子 CREATE OR REPLACE TABLE hits ip bigint page VARCHAR 256 agent VARCHAR 1000 date datetime 我想计算每个页面的 googlebot 访问频率
  • 测验程序的 MySql 数据库设计

    我目前正在开发一个项目 主要是创建一个测验应用程序 它将能够进行包含 10 到 20 个问题的多项选择题或简答题的测验 它需要能够根据正确答案检查用户的答案 然后对用户的答案进行评分 稍后 我可能会实现一个后端功能来在线创建测验 但现在我将
  • 自动将范围内的值插入表中

    是否可以使用 MySQL 语句自动将值插入表中 即从 30 到 200 这是一个应该执行此操作的存储过程 CREATE PROCEDURE insert range BEGIN DECLARE i INT DEFAULT 30 WHILE
  • 未找到教义列:1054“字段列表”中未知列“s.features”

    我在站点表中添加了一个新列 features 并使用 Doctrine 重新生成了模型 此代码导致错误 siteTable Doctrine Core getTable Site site siteTable gt findOneByNam

随机推荐