草庐IT

MySQL 查找最接近或完全匹配的值与更改查找列

coder 2023-10-22 原文

我有以下几组数据...

状态监测位置数据(CML表)

+--------+--------------------+--------------------+--------------+------------+--------------------+-------+-----+
| CML_ID |     POF_COLUMN     |      CML_TYPE      | SAMPLE_VALUE | COMPLIANCE | CORROSION_SEVERITY | LR_LD | POF |
+--------+--------------------+--------------------+--------------+------------+--------------------+-------+-----+
|      1 | SAMPLE_VALUE       | MIC_SAMPLING_POINT |            5 | NO         | MINOR              |     1 |     |
|      2 | SAMPLE_VALUE       | MIC_SAMPLING_POINT |          0.5 | NO         | MINOR              |     2 |     |
|      3 | SAMPLE_VALUE       | MIC_SAMPLING_POINT |           20 | NO         | MINOR              |     3 |     |
|      4 | COMPLIANCE         | VALVE_ROTATED      |            0 | YES        | MINOR              |     4 |     |
|      5 | LR_LD              | PIPING_THICKNESS   |            0 | YES        | MINOR              |   0.1 |     |
|      6 | CORROSION_SEVERITY | VESSEL_SHELL       |            0 | NO         | SEVERE             |     0 |     |
|      7 | CORROSION_SEVERITY | NOZZLE             |            0 | NO         | LOW                |     0 |     |
+--------+--------------------+--------------------+--------------+------------+--------------------+-------+-----+

查找失败概率数据(POF表)

+--------------------+--------------------+-------------+-----+
|     POF_COLUMN     |      CML_TYPE      | VALUE_RANGE | POF |
+--------------------+--------------------+-------------+-----+
| SAMPLE_VALUE       | MIC_SAMPLING_POINT | 1           |   5 |
| SAMPLE_VALUE       | MIC_SAMPLING_POINT | 5           |   4 |
| SAMPLE_VALUE       | MIC_SAMPLING_POINT | 10          |   3 |
| SAMPLE_VALUE       | MIC_SAMPLING_POINT | 15          |   2 |
| SAMPLE_VALUE       | MIC_SAMPLING_POINT | 100         |   1 |
| COMPLIANCE         | VALVE_ROTATED      | YES         |   5 |
| COMPLIANCE         | VALVE_ROTATED      | NO          |   1 |
| LR_LD              | PIPING_THICKNESS   | 2           |   5 |
| LR_LD              | PIPING_THICKNESS   | 1.5         |   4 |
| LR_LD              | PIPING_THICKNESS   | 1           |   3 |
| LR_LD              | PIPING_THICKNESS   | 0.8         |   2 |
| LR_LD              | PIPING_THICKNESS   | 0.5         |   1 |
| CORROSION_SEVERITY | VESSEL_SHELL       | NEGLIGIBLE  |   5 |
| CORROSION_SEVERITY | VESSEL_SHELL       | LOW         |   4 |
| CORROSION_SEVERITY | VESSEL_SHELL       | MEDIUM      |   3 |
| CORROSION_SEVERITY | VESSEL_SHELL       | HIGH        |   2 |
| CORROSION_SEVERITY | VESSEL_SHELL       | SEVERE      |   1 |
| CORROSION_SEVERITY | NOZZLE             | NEGLIGIBLE  |   5 |
| CORROSION_SEVERITY | NOZZLE             | LOW         |   5 |
| CORROSION_SEVERITY | NOZZLE             | MEDIUM      |   5 |
| CORROSION_SEVERITY | NOZZLE             | HIGH        |   3 |
| CORROSION_SEVERITY | NOZZLE             | SEVERE      |   2 |
+--------------------+--------------------+-------------+-----+

并且我需要使用 [POF_Column]、[CML_Type] 以及每个 CML 记录的 [SAMPLE_VALUE]、[COMPLIANCE]、[CORROSION_SEVERITY] 或 [LR_LD] 字段返回 POF 表中最接近或完全匹配的记录在 CML 表中。然后更新记录POF到CML表。

例如,如果我们查看 CML_ID = 2。

按 [POF_COLUMN] = 'SAMPLE_VALUE'、[CML_TYPE] = 'MIC_SAMPLING_POINT' 和 [VALUE_RANGE] 过滤 POF 表 - [SAMPLE_VALUE] 列中的值(在本例中为 0.5)是最小值。

在这种情况下,它将匹配 POF 表中的第一条记录并返回值 POF = 5。

如果我们再看一个案例。 CML_ID = 7。

通过 [POF_COLUMN] = 'CORROSION_SEVERITY'、[CML_TYPE] = 'NOZZLE' 和 [VALUE_RANGE] = [CORROSION_SEVERITY] 列中的值过滤 POF 表,在本例中为“LOW”。

在这种情况下,它将匹配 POF 表中从底部开始的第四行并返回 POF = 5 的值。

总而言之,我需要更新 CML 表以显示以下结果...

+--------+---+-----+
| CML_ID | … | POF |
+--------+---+-----+
|      1 | … |   4 |
|      2 | … |   5 |
|      3 | … |   2 |
|      4 | … |   5 |
|      5 | … |   1 |
|      6 | … |   1 |
|      7 | … |   5 |
+--------+---+-----+

有谁知道我怎样才能做到这一点?我在下面放置了一些我尝试的示例代码。这适用于查找完全匹配的值,但不适用于最接近的匹配值。

DROP DATABASE IF EXISTS VESSELS;
CREATE DATABASE VESSELS;
USE VESSELS;

CREATE TABLE CML (
  `CML_ID`              INTEGER NOT NULL,
  `POF_COLUMN`          VARCHAR(50),
  `CML_TYPE`            VARCHAR(50),
  `SAMPLE_VALUE`        FLOAT,
  `COMPLIANCE`          ENUM('YES','NO'),
  `CORROSION_SEVERITY`  VARCHAR(50),
  `LR_LD`               FLOAT,
  `POF`                 TINYINT,
  PRIMARY KEY (CML_ID)
);

CREATE TABLE POF (
  `POF_COLUMN`   VARCHAR(50),
  `CML_TYPE`     VARCHAR(50),
  `VALUE_RANGE`  VARCHAR(100),
  `POF`          TINYINT,
  PRIMARY KEY (POF_COLUMN, CML_TYPE, VALUE_RANGE)
);

INSERT INTO CML 
VALUES (1, 'SAMPLE_VALUE', 'MIC_SAMPLING_POINT', 5, 'NO', 'MINOR', 1, NULL),
       (2, 'SAMPLE_VALUE', 'MIC_SAMPLING_POINT', 0.5, 'NO', 'MINOR', 2, NULL),
       (3, 'SAMPLE_VALUE', 'MIC_SAMPLING_POINT', 20, 'NO', 'MINOR', 3, NULL), 
       (4, 'COMPLIANCE', 'VALVE_ROTATED', 0, 'YES', 'MINOR', 4, NULL), 
       (5, 'LR_LD', 'PIPING_THICKNESS', 0, 'YES', 'MINOR', 0.1, NULL),
       (6, 'CORROSION_SEVERITY', 'VESSEL_SHELL', 0, 'NO', 'SEVERE', 0, NULL),
       (7, 'CORROSION_SEVERITY', 'NOZZLE', 0, 'NO', 'LOW', 0, NULL);

INSERT INTO POF 
VALUES ('SAMPLE_VALUE', 'MIC_SAMPLING_POINT', 1, 5),
       ('SAMPLE_VALUE', 'MIC_SAMPLING_POINT', 5, 4),
       ('SAMPLE_VALUE', 'MIC_SAMPLING_POINT', 10, 3),
       ('SAMPLE_VALUE', 'MIC_SAMPLING_POINT', 15, 2),
       ('SAMPLE_VALUE', 'MIC_SAMPLING_POINT', 100, 1),
       ('COMPLIANCE', 'VALVE_ROTATED', 'YES', 5), 
       ('COMPLIANCE', 'VALVE_ROTATED', 'NO', 1), 
       ('LR_LD', 'PIPING_THICKNESS', 2, 5),
       ('LR_LD', 'PIPING_THICKNESS', 1.5, 4),
       ('LR_LD', 'PIPING_THICKNESS', 1, 3),
       ('LR_LD', 'PIPING_THICKNESS', 0.8, 2),
       ('LR_LD', 'PIPING_THICKNESS', 0.5, 1),
       ('CORROSION_SEVERITY', 'VESSEL_SHELL', 'NEGLIGIBLE', 5),
       ('CORROSION_SEVERITY', 'VESSEL_SHELL', 'LOW', 4),
       ('CORROSION_SEVERITY', 'VESSEL_SHELL', 'MEDIUM', 3),
       ('CORROSION_SEVERITY', 'VESSEL_SHELL', 'HIGH', 2),
       ('CORROSION_SEVERITY', 'VESSEL_SHELL', 'SEVERE', 1),
       ('CORROSION_SEVERITY', 'NOZZLE', 'NEGLIGIBLE', 5),
       ('CORROSION_SEVERITY', 'NOZZLE', 'LOW', 5),
       ('CORROSION_SEVERITY', 'NOZZLE', 'MEDIUM', 5),
       ('CORROSION_SEVERITY', 'NOZZLE', 'HIGH', 3),
       ('CORROSION_SEVERITY', 'NOZZLE', 'SEVERE', 2);

-- UPDATE EXACT MATCHING VALUE
UPDATE CML c
LEFT JOIN POF p
ON c.POF_COLUMN = p.POF_COLUMN
   AND c.CML_TYPE = p.CML_TYPE
   AND ( (c.POF_COLUMN = 'COMPLIANCE' AND c.COMPLIANCE = p.VALUE_RANGE) OR
         (c.POF_COLUMN = 'SAMPLE_VALUE' AND c.SAMPLE_VALUE = p.VALUE_RANGE) OR
         (c.POF_COLUMN = 'LR_LD' AND c.LR_LD = p.VALUE_RANGE) OR
         (c.POF_COLUMN = 'CORROSION_SEVERITY' AND c.CORROSION_SEVERITY = p.VALUE_RANGE)
       )
SET c.POF = p.POF;

SELECT * FROM CML;

最佳答案

为包含示例数据和预期结果的非常详细的帖子点赞。 问题出在 sample_value 和 lr_ld 上,因为它可能不是 POF 表中的准确值。但是,您会注意到这些值等于或小于值范围。

因此,如果我们得到POF值的最大值,其中sample_value或lr_ld小于或等于取值范围,那么我们只需要得到POF值的最大值。

只有当 sample_value 或 lr_ld 增加时 POF 值增加,此查询才有效。

UPDATE CML c
  JOIN 
(
    select c.CML_ID, max(p.POF) POF 
    from CML c
    LEFT JOIN POF p
    ON c.POF_COLUMN = p.POF_COLUMN
       AND c.CML_TYPE = p.CML_TYPE
       AND ( (c.POF_COLUMN = 'COMPLIANCE' AND c.COMPLIANCE = p.VALUE_RANGE) OR
             (c.POF_COLUMN = 'SAMPLE_VALUE' AND  c.SAMPLE_VALUE<=p.VALUE_RANGE) OR
             (c.POF_COLUMN = 'LR_LD' AND c.LR_LD  <= p.VALUE_RANGE) OR
             (c.POF_COLUMN = 'CORROSION_SEVERITY' AND c.CORROSION_SEVERITY = p.VALUE_RANGE)
           )
     group by c.CML_ID 
   ) t
 on c.CML_ID = t.CML_ID
set c.POF = t.POF;

关于MySQL 查找最接近或完全匹配的值与更改查找列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49268185/

有关MySQL 查找最接近或完全匹配的值与更改查找列的更多相关文章

  1. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

    如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

  2. ruby - 完全离线安装RVM - 2

    我打算为ruby​​脚本创建一个安装程序,但我希望能够确保机器安装了RVM。有没有一种方法可以完全离线安装RVM并且不引人注目(通过不引人注目,就像创建一个可以做所有事情的脚本而不是要求用户向他们的bash_profile或bashrc添加一些东西)我不是要脚本本身,只是一个关于如何走这条路的快速指针(如果可能的话)。我们还研究了这个很有帮助的问题:RVM-isthereawayforsimpleofflineinstall?但有点误导,因为答案只向我们展示了如何离线在RVM中安装ruby。我们需要能够离线安装RVM本身,并查看脚本https://raw.github.com/wayn

  3. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  4. ruby - 匹配未转义的平衡定界符对 - 2

    如何匹配未被反斜杠转义的平衡定界符对(其本身未被反斜杠转义)(无需考虑嵌套)?例如对于反引号,我试过了,但是转义的反引号没有像转义那样工作。regex=/(?!$1:"how\\"#expected"how\\`are"上面的正则表达式不考虑由反斜杠转义并位于反引号前面的反斜杠,但我愿意考虑。StackOverflow如何做到这一点?这样做的目的并不复杂。我有文档文本,其中包括内联代码的反引号,就像StackOverflow一样,我想在HTML文件中显示它,内联代码用一些spanMaterial装饰。不会有嵌套,但转义反引号或转义反斜杠可能出现在任何地方。

  5. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  6. ruby - Capistrano 3 在任务中更改 ssh_options - 2

    我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe

  7. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  8. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  9. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

  10. ruby - 匹配大写字母并用后续字母填充,直到一定的字符串长度 - 2

    我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种

随机推荐