【问题标题】:SQL parse column string for numerical data and store in separate columnsSQL 解析数字数据的列字符串并存储在单独的列中
【发布时间】:2015-03-12 04:44:29
【问题描述】:

我正在使用 Oracle SQL,并且想从通常像这样的单列字符串中解析

suitjacket 899, height195cm weight80kg male
blazerjacket 1099, height170cm weight65kg female
pants 299, height160cm weight89kgs male
coat 1099, height165cms weight60.5kg female

请注意,有时单位是复数形式,末尾带有额外的“s”。如何使用符合 Oracle 标准的 SQL 查询将 heightweight 数据提取到它们自己的单独列中?

| height | weight |
-------------------
|   195  |   80   |
|   170  |   65   |
|   160  |   89   |
|   165  |   60.5 |

我想我必须使用substringregexsubstring 似乎不合适,因为字符串中的数据位置不固定。 regex 似乎更好,但我不确定如何制作regex,然后将其存储在单独的列中,一列用于height,另一列用于weight

【问题讨论】:

  • 我认为这是一个简单的 SUBSTR 和 INSTR 用例。我已经编辑了问题并格式化了。投票重新提出问题。
  • 我看到问题现在重新打开,请参阅我建议的 SUBSTR 和 INSTR 的答案。

标签: sql regex oracle substr


【解决方案1】:

给定一个示例设置:

CREATE TABLE tbl
    (field varchar(48));

INSERT INTO tbl (field) VALUES ('suitjacket 899, height195cm weight80kg male');
INSERT INTO tbl (field) VALUES ('blazerjacket 1099, height170cm weight65kg female');
INSERT INTO tbl (field) VALUES ('pants 299, height160cm weight89kgs male');
INSERT INTO tbl (field) VALUES ('coat 1099, height165cms weight60.5kg female');

您可以结合使用 regexp_substr 和 replace 函数,如下所示:

select to_number(regexp_substr(field, 'height(\d+\.?\d+)', 1, 1, 'i', 1)) height,
       to_number(regexp_substr(field, 'weight(\d+\.?\d+)', 1, 1, 'i', 1)) weight
  from tbl;

这是上面的demo。以下是一些参考资料:regexp_substrreplaceregex cheat sheet

祝你好运!

【讨论】:

  • 你不需要REPLACE();您可以使用在REGEXP_SUSBTR(). 中指定要返回的子表达式,因此:regexp_substr(s, 'height(\d+\.?\d+)', 1, 1, 'i', 1) as height(您可能应该在转换后显式转换为数字)。
  • @Ben 感谢您的洞察力。我编辑了我的答案和 sqlfiddle 演示以反映您的建议。
【解决方案2】:

使用简单的 SUBSTRINSTR,这将比正则表达式快得多。

让我们看一个有效的测试用例:

SQL> WITH DATA AS(
  2  SELECT 'suitjacket 899, height195cm weight80kg male' str FROM dual UNION ALL
  3  SELECT 'blazerjacket 1099, height170cm weight65kg female' str FROM dual UNION ALL
  4  SELECT 'pants 299, height160cm weight89kgs male' str FROM dual UNION ALL
  5  SELECT 'coat 1099, height165cms weight60.5kg female' str FROM dual
  6  )
  7  SELECT
  8    SUBSTR(str, instr(str, 'height', 1) + LENGTH('height'), instr(str, 'cm', 1) - instr(str, 'height', 1) - LENGTH('height')) height,
  9    SUBSTR(str, instr(str, 'weight', 1)      + LENGTH('weight'), instr(str, 'kg', 1) - instr(str, 'weight', 1) - LENGTH('weight')) weight,
 10    str
 11  FROM DATA
 12  /

HEIGHT     WEIGHT     STR
---------- ---------- ----------------------------------------------------------------------------------------------------
195        80         suitjacket 899, height195cm weight80kg male
170        65         blazerjacket 1099, height170cm weight65kg female
160        89         pants 299, height160cm weight89kgs male
165        60.5       coat 1099, height165cms weight60.5kg female

SQL>

您的查询(将 table_name 替换为您的实际表):

SELECT SUBSTR(str, instr(str, 'height', 1) + LENGTH('height'), instr(str, 'cm', 1) - instr(str, 'height', 1) - LENGTH('height')) height,
  SUBSTR(str, instr(str, 'weight', 1)      + LENGTH('weight'), instr(str, 'kg', 1) - instr(str, 'weight', 1) - LENGTH('weight')) weight,
  str
FROM table_name
/

【讨论】:

    猜你喜欢
    • 2020-02-03
    • 2021-10-26
    • 2019-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 2021-09-28
    相关资源
    最近更新 更多