【问题标题】:SQL split hexastring in different bytesSQL将十六进制字符串拆分为不同的字节
【发布时间】:2017-10-09 07:16:41
【问题描述】:

我有一个像这样的 google bigquery:

    #standardSQL
SELECT
  timestamp,
  CAN_Frame, 
    TRIM(SPLIT(CAN_Frame)[OFFSET(4)]) AS bytes
FROM
  `data.source`  
WHERE
  LENGTH(CAN_Frame) > 1 and
  SUBSTR(TRIM(SPLIT(CAN_Frame)[OFFSET(4)]),1,2) IN ('83', '84')
 ORDER BY
  timestamp DESC
LIMIT
  8000

或者像这样

#standardSQL
SELECT
*  
FROM (
 SELECT
     timestamp,
    CAN_Frame,
    REGEXP_EXTRACT(CAN_Frame, r', ([^,]+)$') AS bytes_string,
    FROM_HEX(REPLACE(REGEXP_EXTRACT(CAN_Frame, r', ([^,]+)$'), ' ', '')) AS 
bytes

  FROM `data.source`
)
WHERE SUBSTR(bytes, 1, 1) IN (b'\x83', b'\x84')

ORDER BY timestamp DESC
LIMIT 8000

使用结果表:

行时间戳 CAN_Frame 字节
1 2017-09-29 14:31:02 UTC S,48778,410,8, 84 10 00 25 00 21 00 4F 84 10 00 25 00 21 00 4F
2 2017-09-29 14:30:42 UTC S,35847,480,8, 83 80 00 01 00 03 00 0D 83 80 00 01 00 03 00 0D
3 2017-09-29 14:30:40 UTC S,34612,4B2,8, 84 B2 00 27 00 08 00 03 84 B2 00 27 00 08 00 03

行时间戳 CAN_Frame bytes_string bytes
1 2017-09-29 14:31:02 UTC S,48778,410,8, 84 10 00 25 00 21 00 4F 84 10 00 25 00 21 00 4F hBAAJQAhAE8=
2 2017-09-29 14:30:42 UTC S,35847,480,8, 83 80 00 01 00 03 00 0D 83 80 00 01 00 03 00 0D g4AAAQADAA0=
3 2017-09-29 14:30:40 UTC S,34612,4B2,8, 84 B2 00 27 00 08 00 03 84 B2 00 27 00 08 00 03 hLIAJwAIAAM=
4 2017-09-29 14:30:39 UTC S,34314,4C0,8, 84 C0 00 1C 00 15 00 07 84 C0 00 1C 00 15 00 07 hMAAHAAVAAc=

我现在的问题和问题是如何拆分 8 字节的十六进制字符串,让我有以 83 开头的字符串的第 6 和第 7 字节,从 83 开始的第 8 字节和从 84 开始的第 3 字节和第 4 和字符串的第 5 个字节以 84 开头。这些数据对是我需要读取的无符号整数中 lsb msb 的值。

我希望有人可以帮助我或至少了解我的问题。

最好的问候

【问题讨论】:

    标签: mysql string split hex google-bigquery


    【解决方案1】:
    #standardSQL
    WITH `data.source` AS (
      SELECT 'S,0,2B3,8, C2 B3 00 00 00 00 03 DE' AS frame UNION ALL
      SELECT 'S,0,3FA,6, 00 E0 04 A5 00 0B' UNION ALL
      SELECT 'S,0,440,8, 83 40 4E A5 00 47 00 64' UNION ALL
      SELECT 'S,0,450,8, 84 50 01 12 01 19 01 B3' UNION ALL
      SELECT 'S,0,4B0,8, 84 B0 4E A5 00 43 00 64' 
    )
    SELECT
      frame, bytes, STRING_AGG(b, ' ' ORDER BY p) AS selected_bytes
    FROM (
      SELECT frame, TRIM(SPLIT(frame)[OFFSET(4)]) AS bytes, SUBSTR(TRIM(SPLIT(frame)[OFFSET(4)]), 1, 2) AS f
      FROM `data.source`
      WHERE SUBSTR(TRIM(SPLIT(frame)[OFFSET(4)]), 1, 2) IN ('83', '84')
    ), UNNEST(SPLIT(bytes, ' ')) AS b WITH OFFSET AS p
    WHERE CASE f WHEN '83' THEN p IN (5, 6, 7) WHEN '84' THEN p IN (2, 3, 4) END
    GROUP BY frame, bytes
    -- ORDER BY frame
    

    结果是:

    frame                               bytes                       selected_bytes
    S,0,440,8, 83 40 4E A5 00 47 00 64  83 40 4E A5 00 47 00 64     47 00 64
    S,0,450,8, 84 50 01 12 01 19 01 B3  84 50 01 12 01 19 01 B3     01 12 01
    S,0,4B0,8, 84 B0 4E A5 00 43 00 64  84 B0 4E A5 00 43 00 64     4E A5 00
    

    更新:

    以 83 开头的字符串中的字节 6 和 7 称为 Aiout
    一列包含以 83 开头的字符串中的字节 8 和以 84 开头的字符串中的字节 3,称为 Biout
    一列包含以 84 开头的字符串中的字节 4 和 5,称为 Avout
    bvout 包含以 84 开头的字符串中的字节 6 和 7

    #standardSQL
    WITH `data.source` AS (
      SELECT 'S,0,2B3,8, C2 B3 00 00 00 00 03 DE' AS frame UNION ALL
      SELECT 'S,0,3FA,6, 00 E0 04 A5 00 0B' UNION ALL
      SELECT 'S,0,440,8, 83 40 4E A5 00 47 00 64' UNION ALL
      SELECT 'S,0,450,8, 84 50 01 12 01 19 01 B3' UNION ALL
      SELECT 'S,0,4B0,8, 84 B0 4E A5 00 43 00 64' 
    )
    SELECT
      frame, bytes, 
      STRING_AGG(CASE WHEN f='83' AND p IN (5, 6) THEN b ELSE '' END, ' ' ORDER BY p) AS Aiout,
      STRING_AGG(CASE WHEN (f='83' AND p=7) OR (f='84' AND p=2)  THEN b ELSE '' END, ' ' ORDER BY p) AS Biout,
      STRING_AGG(CASE WHEN f='84' AND p IN (3, 4) THEN b ELSE '' END, ' ' ORDER BY p) AS Avout,
      STRING_AGG(CASE WHEN f='84' AND p IN (5, 6) THEN b ELSE '' END, ' ' ORDER BY p) AS Bvout
    FROM (
      SELECT frame, TRIM(SPLIT(frame)[OFFSET(4)]) AS bytes, SUBSTR(TRIM(SPLIT(frame)[OFFSET(4)]), 1, 2) AS f
      FROM `data.source`
      WHERE SUBSTR(TRIM(SPLIT(frame)[OFFSET(4)]), 1, 2) IN ('83', '84')
    ), UNNEST(SPLIT(bytes, ' ')) AS b WITH OFFSET AS p
    GROUP BY frame, bytes
    ORDER BY frame
    

    输出为

    frame                               bytes                   Aiout   Biout   Avout   Bvout
    S,0,440,8, 83 40 4E A5 00 47 00 64  83 40 4E A5 00 47 00 64 47 00   64
    S,0,450,8, 84 50 01 12 01 19 01 B3  84 50 01 12 01 19 01 B3         01      12 01   19 01
    S,0,4B0,8, 84 B0 4E A5 00 43 00 64  84 B0 4E A5 00 43 00 64         4E      A5 00   43 00
    

    【讨论】:

    • 感谢这种方法。最终我需要从字节中提取 4 列。一列包含以 83 开头的字符串中的字节 6 和 7,称为 Aiout;一列包含以 83 开头的字符串中的字节 8 和以 84 开头的字符串中的字节 3,称为 Biout;一列包含以 84 开头的字符串中的字节 4 和 5,称为 Avout,最后一列是 Bvout,包含以 84 开头的字符串中的字节 6 和 7。
    • 我想你可能想自己做一些额外的事情?答案中显示的示例对此已经足够了,不是吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 2017-08-23
    • 2014-10-09
    • 2023-03-07
    • 2022-06-18
    • 2014-03-10
    相关资源
    最近更新 更多