Ниже для BigQuery Standard SQL
#standardSQL
SELECT `date`,
SPLIT(kv, ':')[OFFSET(0)] id_name,
SPLIT(kv, ':')[OFFSET(1)] id
FROM `project.dataset.table` t,
UNNEST(SPLIT(REGEXP_REPLACE(TO_JSON_STRING(t), r'[{}"]', ''))) kv
WHERE SPLIT(kv, ':')[OFFSET(0)] != 'date'
, если применить к образцу данных из вашего вопроса, как в примере ниже
#standardSQL
WITH `project.dataset.table` AS (
SELECT DATE '2020-04-01' `date`, 'Shift A' ldap1, 'Shift B' ldap2, 'Shift C' ldap3 UNION ALL
SELECT '2020-04-02', 'Shift A', 'Shift B', 'Shift C' UNION ALL
SELECT '2020-04-03', 'Shift A', 'Shift B', 'Shift C'
)
SELECT `date`,
SPLIT(kv, ':')[OFFSET(0)] id_name,
SPLIT(kv, ':')[OFFSET(1)] id
FROM `project.dataset.table` t,
UNNEST(SPLIT(REGEXP_REPLACE(TO_JSON_STRING(t), r'[{}"]', ''))) kv
WHERE SPLIT(kv, ':')[OFFSET(0)] != 'date'
результат равен
Row date id_name id
1 2020-04-01 ldap1 Shift A
2 2020-04-01 ldap2 Shift B
3 2020-04-01 ldap3 Shift C
4 2020-04-02 ldap1 Shift A
5 2020-04-02 ldap2 Shift B
6 2020-04-02 ldap3 Shift C
7 2020-04-03 ldap1 Shift A
8 2020-04-03 ldap2 Shift B
9 2020-04-03 ldap3 Shift C
Вышеприведенный запрос может быть подвергнут дальнейшему рефакторингу (зависит от ваших вкусов)
#standardSQL
SELECT `date`, id_name, id
FROM `project.dataset.table` t,
UNNEST(SPLIT(REGEXP_REPLACE(TO_JSON_STRING(t), r'[{}"]', ''))) kv,
UNNEST([STRUCT(SPLIT(kv, ':')[OFFSET(0)] AS id_name, SPLIT(kv, ':')[OFFSET(1)] AS id)])
WHERE id_name != 'date'
этот позволяет избежать лишних частей и немного меньше подробностей