Ниже для BigQuery Standard SQL
Скорее всего, количество языков в ваших данных заранее неизвестно - поэтому я рекомендую следующий подход, который сначала собирает все языки в данные и размещает их в алфавитном порядке, а затем для каждой строки выдает вектор из 0 и 1, представляющий существование соответствующих язык в зависимости от их положения в этом списке базовых языков
#standardSQL
WITH `project.dataset.table` AS (
SELECT 'French,English' langs UNION ALL
SELECT 'Dutch,French,English' UNION ALL
SELECT 'English' UNION ALL
SELECT 'French,Dutch'
), base AS (
SELECT STRING_AGG(lang ORDER BY lang) all_langs
FROM (
SELECT DISTINCT lang
FROM `project.dataset.table`,
UNNEST(SPLIT(langs)) lang
)
)
SELECT langs, all_langs,
(SELECT STRING_AGG(IF(lang IS NULL, '0', '1') ORDER BY pos)
FROM UNNEST(SPLIT(all_langs)) base_lang WITH OFFSET pos
LEFT JOIN UNNEST(SPLIT(langs)) lang
ON base_lang = lang
) AS value
FROM `project.dataset.table` t
CROSS JOIN base b
результат
Row langs all_langs value
1 French,English Dutch,English,French 0,1,1
2 Dutch,French,English Dutch,English,French 1,1,1
3 English Dutch,English,French 0,1,0
4 French,Dutch Dutch,English,French 1,0,1
Надеюсь, это даст вам хорошую отправную точку для вашего конкретного случая использования
Примечание: BigQuery не поддерживает нативную PIVOT'ing, поэтому вышеуказанный подход, скорее всего, наиболее оптимальный для вас
... мои строки уже являются массивом строк ... У меня есть ["французский", "английский"] вместо "французский, английский" ... Так это все еще работает?
Абсолютно - Да! Единственное изменение, которое вам нужно сделать, это заменить UNNEST(SPLIT(langs))
на UNNEST(langs)
, как в примере ниже
#standardSQL
WITH `project.dataset.table` AS (
SELECT ['French','English'] langs UNION ALL
SELECT ['Dutch','French','English'] UNION ALL
SELECT ['English'] UNION ALL
SELECT ['French','Dutch']
), base AS (
SELECT STRING_AGG(lang ORDER BY lang) all_langs
FROM (
SELECT DISTINCT lang
FROM `project.dataset.table`,
UNNEST(langs) lang
)
)
SELECT langs, all_langs,
(SELECT STRING_AGG(IF(lang IS NULL, '0', '1') ORDER BY pos)
FROM UNNEST(SPLIT(all_langs)) base_lang WITH OFFSET pos
LEFT JOIN UNNEST(langs) lang
ON base_lang = lang
) AS value
FROM `project.dataset.table` t
CROSS JOIN base b
с результатом
если строка [Французский, английский, английский]. желаемый - 0,1,2
см. Пример ниже
#standardSQL
WITH `project.dataset.table` AS (
SELECT ['French','English','English'] langs UNION ALL
SELECT ['Dutch','French','English'] UNION ALL
SELECT ['English','English'] UNION ALL
SELECT ['French','Dutch']
), base AS (
SELECT STRING_AGG(lang ORDER BY lang) all_langs
FROM (
SELECT DISTINCT lang
FROM `project.dataset.table`,
UNNEST(langs) lang
)
)
SELECT langs, all_langs,
ARRAY_TO_STRING(ARRAY(SELECT CAST(SUM(IF(lang IS NULL, 0, 1)) AS STRING)
FROM UNNEST(SPLIT(all_langs)) base_lang WITH OFFSET pos
LEFT JOIN UNNEST(langs) lang
ON base_lang = lang
GROUP BY base_lang
ORDER BY MIN(pos)
), ',') AS value
FROM `project.dataset.table` t
CROSS JOIN base b
с результатом