#sql #arrays #google-cloud-platform #google-bigquery
#sql #массивы #google-облачная платформа #google-большой запрос
Вопрос:
Есть ли какой-нибудь простой метод для объединения значений в пакеты (с сохранением порядка)
из этого
key | value
---- ------
a | 1
a | 2
a | 3
a | 4
a | 5
a | 6
b | 9
b | 8
b | 7
b | 6
b | 5
b | 4
к этому
key | batches
---- -------------------------------------------------------------
a | [{'values': [1, 2]}, {'values': [3, 4]}, {'values': [5, 6]}]
b | [{'values': [9, 8]}, {'values': [7, 6]}, {'values': [5, 4]}]
{'values': [1, 2]}
— СТРУКТУРА
[{'values': [1, 2]}, {'values': [3, 4]}, {'values': [5, 6]}]
— ПОВТОРЯЮЩИЕСЯ СТРУКТУРЫ
Ответ №1:
Для BigQuery стандартный SQL
Есть ли какой-нибудь простой метод для объединения значений в пакеты (с сохранением порядка)
Примечание; чтобы «сохранить порядок» — вам нужно иметь какое-то указание на этот порядок в ваших данных — я предполагаю, что у вас есть что-то, что определяет этот порядок (я использую ts
поле для этого) — обычно это временная метка или тип данных order / position и т.д.
Итак, ниже приведена отправная точка для достижения точно указанной цели
#standardSQL
SELECT key,
ARRAY_AGG(value ORDER BY pos) AS batch,
DIV(pos - 1, 2) batch_num
FROM (
SELECT *,
ROW_NUMBER() OVER(PARTITION BY key ORDER BY ts) pos,
DIV(ROW_NUMBER() OVER(PARTITION BY key ORDER BY ts) - 1, 2) batch
FROM `project.dataset.table`
)
GROUP BY key, batch_num
Если применить к образцу данных из вашего вопроса — вывод
Отсюда вы можете упаковать приведенный выше результат в любой конечный формат, который вам нужен, например
#standardSQL
SELECT key, ARRAY_AGG(batch ORDER BY batch_num) batches
FROM (
SELECT key,
STRUCT(ARRAY_AGG(value ORDER BY pos) AS values) batch,
DIV(pos - 1, 2) batch_num
FROM (
SELECT *,
ROW_NUMBER() OVER(PARTITION BY key ORDER BY ts) pos,
DIV(ROW_NUMBER() OVER(PARTITION BY key ORDER BY ts) - 1, 2) batch
FROM `project.dataset.table`
)
GROUP BY key, batch_num
)
GROUP BY key
которые дают вывод ниже (довольно близкий к ожидаемому примеру в вашем вопросе)
[
{
"key": "a",
"batches": [
{
"values": [
"1",
"2"
]
},
{
"values": [
"3",
"4"
]
},
{
"values": [
"5",
"6"
]
}
]
},
{
"key": "b",
"batches": [
{
"values": [
"9",
"8"
]
},
{
"values": [
"7",
"6"
]
},
{
"values": [
"5",
"4"
]
}
]
}
]
Комментарии:
1. но
OVER(PARTITION BY key ORDER BY True)
не гарантирует порядок?2. Я нигде не вижу
ORDER BY True
в своем ответе! пожалуйста, уточните свой комментарий, а также прочитайте еще раз примечание поверх моего ответа: o)3. извините. Я имел в виду, что я хочу заменить
OVER(PARTITION BY key ORDER BY ts)
наOVER(PARTITION BY key ORDER BY True)
, если в исходной таблице нет чего-то вроде метки времени.4. Если у вас нет никакого поля, которое вы могли бы использовать в качестве указания порядка — это означает, что в ваших данных нет никакого порядка и, следовательно, к сожалению, нечего сохранять — поэтому вы можете просто удалить order by to part — так что вы все равно получите пакеты, но порядок не будет гарантирован