【问题标题】:Parsing within a field using SQL使用 SQL 在字段内解析
【发布时间】:2021-09-10 09:16:03
【问题描述】:

我们在需要进一步解析的一列中接收数据。在此示例中,分隔符是 ~。 目标是从其各自的对中获取通过或失败的值。

SL Data
1 "PARAM-0040,PASS~PARAM-0045,PASS~PARAM-0070,PASS"
2 "PARAM-0040,FAIL~PARAM-0045,FAIL~PARAM-0070,PASS"

要求的结果:

SL PARAM-0040 PARAM-0045 PARAM-0070
1 PASS PASS PASS
2 FAIL FAIL PASS

这将是一个更大的 SQL 查询的一部分,我们将在其中选择许多其他列,这三列也将从源中提取并作为选定列传递给查询。

例如

Select Column1, Column2, [ Parse code ] as PARAM-0040, [ Parse code ] as PARAM-0045, [ Parse code ] as PARAM-0070, Column6 ..... 

谢谢

【问题讨论】:

  • 你需要标记你正在使用的dbms
  • 完成。此查询旨在从配置单元表中提取数据。
  • 火花版本?
  • @Arctic 使用 str_to_map 提出的答案是否适合您?

标签: sql apache-spark parsing hive


【解决方案1】:

您可以使用正则表达式来做到这一点。但是正则表达式是非标准的。 在 postgresql 中是这样完成的:REGEXP_MATCHES()

https://www.postgresqltutorial.com/postgresql-regexp_matches/

在 postgresql 中,regexp_matches 返回零个或多个值。因此,它必须被分解(因此是 {})

在 postgresql 中还有一种更简单的方法是使用子字符串。

substring('foobar' from 'o(.)b')

喜欢:

select substring('PARAM-0040,PASS~PARAM-0045,PASS~PARAM-0070,PASS' from 'PARAM-0040,([^~]+)~');
 substring 
-----------
 PASS
(1 row)

【讨论】:

  • 这看起来是个好方法。关于用“{...}”返回的答案。然后这进一步需要清理..这是一个参数来清理它的结果吗?
  • 查看更新的答案。如果您使用的是 postgresql,则 substring 更易于使用。
  • 子字符串也是我一开始就想到的,而且效果很好。不过,我们不知道数据的顺序是否每次都相同。
  • 你总是可以制作一个对位置有弹性的正则表达式(基本上,使正则表达式在字符串末尾或波浪号结尾。
  • 两者的结合就像一个魅力: substring(regexp_extract(data, '(PARAM-0040,(.{4}))'), 12,4) REGEXP_MATCHES() 似乎没有在我们可用的功能列表中。
【解决方案2】:

您可以使用str_to_map 函数来拆分您的数据,然后提取每个参数的值。此示例将首先将每个参数/值对按~ 拆分,然后再按, 拆分参数和值。

您的示例数据的可重现示例:

WITH my_table AS (
    SELECT 1 as SL, "PARAM-0040,PASS~PARAM-0045,PASS~PARAM-0070,PASS" as DATA
    UNION ALL
    SELECT 2 as SL, "PARAM-0040,FAIL~PARAM-0045,FAIL~PARAM-0070,PASS" as DATA
),
param_mapped_data AS (
   SELECT SL, str_to_map(DATA,"~",",") param_map FROM my_table
)
SELECT
    SL,
    param_map['PARAM-0040'] AS  PARAM0040,
    param_map['PARAM-0045'] AS  PARAM0045,
    param_map['PARAM-0070'] AS  PARAM0070
FROM 
   param_mapped_data

假设您的表名为my_table的实际代码

WITH param_mapped_data AS (
   SELECT SL, str_to_map(DATA,"~",",") param_map FROM my_table
)
SELECT
    SL,
    param_map['PARAM-0040'] AS  PARAM0040,
    param_map['PARAM-0045'] AS  PARAM0045,
    param_map['PARAM-0070'] AS  PARAM0070
FROM 
   param_mapped_data

输出:

sl param0040 param0045 param0070
1 PASS PASS PASS
2 FAIL FAIL PASS

【讨论】:

    猜你喜欢
    • 2010-10-19
    • 1970-01-01
    • 2015-10-14
    • 1970-01-01
    • 2014-10-22
    • 2020-04-01
    • 1970-01-01
    • 2020-01-21
    • 2021-03-26
    相关资源
    最近更新 更多