Mysql
 sql >> Database >  >> RDS >> Mysql

Stringa esadecimale divisa in SQL in byte diversi

#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

il risultato è:

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

Aggiornamento per:

#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

con uscita come

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