【问题标题】:Parsing Though MySQL Column to Extract Data解析 MySQL 列以提取数据
【发布时间】:2019-09-07 07:46:40
【问题描述】:

在 1950 年代汽车零件书的数字化版本中,模型条目被设计为人眼可以阅读,因此为了节省空间,它们被缩写了。当然,这不适用于我的搜索引擎,我对正则表达式知之甚少,对 REGEXP 更是知之甚少,所以希望这里有人能提供帮助。我确实浏览了 MySQL 手册,但恐怕没有这样的东西。数据还有其他变体,但我想从这一点开始。我目前正在使用一个 PHP 脚本进行解析,该脚本需要数小时才能运行,即使它只需要在有更新数据时运行,它也需要很长时间。

这是单行字段中的数据,用分号分隔(注意:这些数据在原始的一行中,但我在此处添加了返回以使其更易于阅读):

2452-62-65-67-72-92-95-98; 
2552-62-65-72-77-92-95; 
2650-51-52-62-65-72-77-92-95-97; 
5450-51-52-62-65-67-72-77-82-85-92-95-97

... 那些需要解析的总是会有破折号,但我需要它以某种方式解析它们看起来像这样。它需要忽略任何文本,因为有些文本有 ALL 24TH 之类的内容; 25 日; 26TH 单独发帖:

2452 2462 2465 2467 2472 2492 2495 2498; 
2552 2562 2565 2572 2577 2592 2595; 
2650 2651 2652 2662 2665 2672 2677 2692 2695 2697; 
5450 5451 5452 5462 5465 5467 5472 5477 5482 5485 5492 5495 5497

这个简单的查询会提取一个四位数字,但我不知道如何继续。

SELECT
    Models 
FROM
    parts_listing
WHERE
     Models REGEXP '^[0-9]{4}$'
ORDER BY Models;

下面是一个基本行的简短示例,或给定零件的模型分组:

2206-13-26-33; 2302-06-13-32-33

... 但该行也可能包含其他信息(我最终也需要解析这些信息),如这些示例中所示。对于第一个和第二个,我们需要解析出 ALL 和序数,对于第三个,我们需要解析出括号之间的任何内容。第四个是一个以 ALL 值开头和结尾但中间有一些破折号分隔值的示例。

ALL 24TH; 25TH; 26TH
2262-65-70-71-72-75-76-77-79-80-82-86-92-93-95; ALL 23RD
5401-11-31 (BODIES 5467-77-97)
ALL 22ND; 2301-02-13-32; ALL 24TH; 25TH; 26TH; 54TH

还有一些带有 LHD(或有时是 RHD),并且在开头或在某些情况下在该行的其他位置,并且后面总是有一个逗号:

LHD, 2401 (BODIES 2462-65-92-95-98); 2501; 2601-33; 5400-33

可能还有其他变体,但目前我只关注基本模型信息。

【问题讨论】:

    标签: mysql parsing


    【解决方案1】:

    如果该行最多包含 9 个部分,这将起作用。
    如果有更多部分的情况,您可以扩展子查询以包含比 9 更多的数字:

    select  
      group_concat(
        replace(t.part, '-', concat(' ', left(t.part, 2)))
        order by t.partno
        separator ' '                                      
      ) Models
    from (
      select t.Models, p.partno,
        replace(replace(
          substring_index(t.Models, ';', p.partno),
          substring_index(t.Models, ';', p.partno - 1),
          ''
        ), ';', '') part 
      from parts_listing t cross join (
        select 1 partno union all select 2 union all select 3 union all
        select 4 union all select 5 union all select 6 union all
        select 7 union all select 8 union all select 9
      ) p 
      where replace(replace(Models, '-', ''), ';', '') regexp'^[0-9]*$'
    ) t
    where t.part <> ''
    group by t.Models
    order by t.Models 
    

    请参阅demo

    【讨论】:

    • 条件:WHERE Models REGEXP '^[0-9]{4}' 删除任何不以 4 位数字开头的行。那么问题出在哪里?
    • 在 where 子句中试试这个:WHERE replace(replace(Models, '-', ''), ';', '') REGEXP '^[0-9]*$'跨度>
    • 第一组是什么意思。你没有提到任何关于组的事情。
    • 看来我错过了这部分:这些在原版中的一行,但我在此处添加了返回以使其更易于阅读您的问题。我认为这些是表中的不同行。现在解决您的问题:您需要 MySql 不提供的拆分字符串功能。如果你能改变设计。分隔的字符串只会导致问题。阅读:stackoverflow.com/questions/1690017/…
    • 我的查询仅适用于第一个分号之前的第一部分。之后,它将第一部分的前 2 位数字添加到所有其他部分,这不是您需要的,对吧?查看演示:db-fiddle.com/f/h7ZJ6nqRGRQbRMTusHYVcr/2 正如我所说,MySql 不提供拆分功能,因此您可以拆分部分并从每个部分中取出前 2 个数字
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 2020-05-30
    • 2012-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多