是否有可能将由两个字节组成的十六进制字符串转换为bytes / int,而第一个字节是lsb,第二个字节是msb。
处理完毕后:
#standardSQL
SELECT
timestamp, CAN_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 timestamp, CAN_Frame, TRIM(SPLIT(CAN_Frame)[OFFSET(4)]) AS bytes,
SUBSTR(TRIM(SPLIT(CAN_Frame)[OFFSET(4)]), 1, 2) AS f
FROM `data.source`
WHERE SUBSTR(TRIM(SPLIT(CAN_Frame)[OFFSET(4)]), 1, 2) IN ('83', '84')
), UNNEST(SPLIT(bytes, ' ')) AS b WITH OFFSET AS p
GROUP BY timestamp,CAN_Frame, bytes
ORDER BY timestamp desc
(感谢Mikhail Berlyant)
我有4列(aiout,biout,avout,bvout),每列包含一个十六进制字符串中的两个字节,如下所示:
Aiout Biout Avout Bvout
00 25 00 21 00
03 00 0D
00 27 00 08 00
00 1C 00 15 00
00 25 00 21 00
03 00 03
00 2A 00 26 00
03 00 0D
00 00 07
04 00 04
使用强制转换,格式化,整数等函数...我总是出现内部错误,无法完成请求。
最好的问候
答案 0 :(得分:1)
以下是基于Mikhail's answer to your previous question构建的示例。它采用以空格分隔的字节,并将它们转换为前缀为0x
的字符串,没有可以转换为int64的空格:
#standardSQL
CREATE TEMP FUNCTION HexToInt(hex_string STRING) AS (
IFNULL(SAFE_CAST(CONCAT('0x', REPLACE(hex_string, ' ', '')) AS INT64), 0)
);
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 *,
HexToInt(Aiout) AS Aiout_int64,
HexToInt(Biout) AS Biout_int64,
HexToInt(Avout) AS Avout_int64,
HexToInt(Bvout) AS Bvout_int64
FROM (
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 | Aiout_int64 | Biout_int64 | Avout_int64 | Bvout_int64 |
+------------------------------------+-------------------------+-------------+-----------+-------------+-------------+-------------+-------------+-------------+-------------+
| S,0,440,8, 83 40 4E A5 00 47 00 64 | 83 40 4E A5 00 47 00 64 | 47 00 | 64 | | | 18176 | 100 | 0 | 0 |
| 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 | 0 | 1 | 4609 | 6401 |
| 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 | 0 | 78 | 42240 | 17152 |
+------------------------------------+-------------------------+-------------+-----------+-------------+-------------+-------------+-------------+-------------+-------------+
编辑:如果要更改解释字节的顺序,可以在转换前反转内容,例如:
#standardSQL
CREATE TEMP FUNCTION HexReverse(hex_string STRING) AS (
(SELECT STRING_AGG(s, ' ' ORDER BY off DESC)
FROM UNNEST(SPLIT(hex_string, ' ')) AS s WITH OFFSET off)
);
CREATE TEMP FUNCTION HexToInt(hex_string STRING) AS (
IFNULL(SAFE_CAST(CONCAT('0x', REPLACE(HexReverse(hex_string), ' ', '')) AS INT64), 0)
);
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 *,
HexToInt(Aiout) AS Aiout_int64,
HexToInt(Biout) AS Biout_int64,
HexToInt(Avout) AS Avout_int64,
HexToInt(Bvout) AS Bvout_int64
FROM (
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
);