首页 > 解决方案 > 为什么这个查询会在 MySQL 5 中运行,但不能在 MySQL 8 中运行

问题描述

我们正在从 MySQL 5 迁移到 8,我发现一个查询可以在 5 中工作,但不能在 8 中工作。

Senario:我正在尝试查找被标记为没有乳房筛查相关数据的记录,但实际上系统中确实有这些数据。我的主要记录是一个循环记录(t_cycle 表)。每个其他相关记录都有指向循环表的链接。在这个简化版的查询中,我正在寻找没有乳房 X 线照片记录但确实有办公室访问或 MRI 的周期。但我只对办公室访问是否有特定结果的程序感兴趣。我通过查询另一个结果表来获取可接受的结果列表。在实际查询中,我加入了多个其他表,但这说明了问题。

这是适用于 5 但不适用于版本 8 的查询:

SELECT 
               cyc.f_enroll_id,
               cyc.f_cycle_number,
               ov.f_cbe_result,
               mri.f_uid as 'MRI'
FROM
               t_cycle cyc LEFT JOIN
               t_mam_rpt mam ON cyc.f_uid = mam.f_cycle_uid LEFT JOIN
               t_office_visit ov ON cyc.f_uid = ov.f_cycle_uid AND ov.f_cbe_result IN (SELECT f_code FROM t_lk_cbe_result WHERE f_mde_code IN (1,2)) LEFT JOIN 
               t_mri mri ON cyc.f_uid = mri.f_cycle_uid 
WHERE
               cyc.f_mam_indication = 5 AND
               mam.f_uid IS NULL AND
               (ov.f_uid IS NOT NULL OR
               mri.f_uid IS NOT NULL);

在第 5 版中,我得到了大约 20 条记录。在第 8 版中,我得到了超过 7000 次,其中大多数都进行了办公室访问,而 CBE 结果不在可接受的结果列表中。

有 2 种变体似乎在 8 中起作用:

/* appears to work (removed the OR mri.f_uid IS NOT NULL) */
SELECT 
               cyc.f_enroll_id,
               cyc.f_cycle_number,
               ov.f_cbe_result,
               mri.f_uid as 'MRI'
FROM
               t_cycle cyc LEFT JOIN
               t_mam_rpt mam ON cyc.f_uid = mam.f_cycle_uid LEFT JOIN
               t_office_visit ov ON cyc.f_uid = ov.f_cycle_uid AND ov.f_cbe_result IN (SELECT f_code FROM t_lk_cbe_result WHERE f_mde_code IN (1,2)) LEFT JOIN 
               t_mri mri ON cyc.f_uid = mri.f_cycle_uid 
WHERE
               cyc.f_mam_indication = 5 AND
               mam.f_uid IS NULL AND
              ov.f_uid IS NOT NULL ;

在上面的版本中,我将 WHERE 子句修改为没有“OR mri.f_uid IS NOT NULL)”,但在实际使用中,这不是一个选项。

这似乎也有效:

/* appears to work - replaced the SELECT in the JOIN with hard coded values that are returned in the select) */
SELECT 
               cyc.f_enroll_id,
               cyc.f_cycle_number,
               ov.f_cbe_result,
               mri.f_uid as 'MRI'
FROM
               t_cycle cyc LEFT JOIN
               t_mam_rpt mam ON cyc.f_uid = mam.f_cycle_uid LEFT JOIN
               t_office_visit ov ON cyc.f_uid = ov.f_cycle_uid AND ov.f_cbe_result IN (2,30,31,33,34,35,38,39,40,42,43,44,45,46,47) LEFT JOIN 
               t_mri mri ON cyc.f_uid = mri.f_cycle_uid 
WHERE
               cyc.f_mam_indication = 5 AND
               mam.f_uid IS NULL AND
               (ov.f_uid IS NOT NULL OR
               mri.f_uid IS NOT NULL);

在上述情况下,我在办公室访问中用 sub-SELECT 替换了一个可接受的结果列表。实际上,我不能这样做,因为该列表会有所不同。

我想我的问题归结为为什么即使办公室访问记录没有正确的结果代码,也会包含在结果集中?

我不经常在这里发帖,所以希望我已经提供了足够的信息。

TIA 寻求帮助!-卡罗琳

附加信息:21 年 8 月 4 日我试图获取一小部分数据来重新创建问题,但它似乎只显示办公室访问表中的大量数据(具有包含子查询的连接的表) )。

如果我从连接中删除子查询,而是离开连接我的代码列表,然后调整 WHERE 子句以在那里进行检查,它可以正常工作。这是修改后的代码的样子:

SELECT 
   cyc.f_enroll_id,
   cyc.f_cycle_number,
   ov.f_cbe_result,
   mri.f_uid as 'MRI'
FROM
   t_cycle cyc LEFT JOIN
   t_office_visit ov ON cyc.f_uid = ov.f_cycle_uid LEFT JOIN
   t_lk_cbe_result lk ON ov.f_cbe_result = lk.f_code LEFT JOIN 
   t_mam_rpt mam ON cyc.f_uid = mam.f_cycle_uid LEFT JOIN
   t_mri mri ON cyc.f_uid = mri.f_cycle_uid 
WHERE
   cyc.f_mam_indication = 5 AND
   mam.f_uid IS NULL AND 
   ((ov.f_uid IS NOT NULL AND lk.f_mde_code IN (1,2)) OR
   mri.f_uid IS NOT NULL)

我们使用的是 8.0.18 版本,因此很可能是评论中提到的已经修复的错误。我们将再次升级,看看是否能解决问题。感谢所有查看此问题的人,如果您知道这是一个已知问题,请随时继续回复。如果有地方可以找到 mySQL 的已知问题,我也会很感激这个链接。

标签: mysqlsql

解决方案


推荐阅读