ищет решение, которое работает, когда количество категорий составляет около 1-10K
Ниже для BigQuery SQL
Шаг 1 - производить динамически запроса (по аналогии с той, которая используется в вашем вопросе - но теперь она строится динамически основывают на вас столе - yourTable
)
#standardSQL
WITH categories AS (SELECT DISTINCT cat FROM yourTable, UNNEST(type) AS cat)
SELECT CONCAT(
"WITH categories AS (SELECT DISTINCT cat FROM yourTable, UNNEST(type) AS cat), ",
"ids AS (SELECT DISTINCT id FROM yourTable), ",
"pairs AS (SELECT id, cat FROM ids CROSS JOIN categories), ",
"flat AS (SELECT id, cat FROM yourTable, UNNEST(type) cat), ",
"combinations AS (",
" SELECT p.id, p.cat AS col, IF(f.cat IS NULL, 0, 1) AS flag ",
" FROM pairs AS p LEFT JOIN flat AS f ",
" ON p.cat = f.cat AND p.id=f.id ",
") ",
"SELECT id, ",
STRING_AGG(CONCAT("SUM(IF(col = '", cat, "', flag, 0)) as is_", cat) ORDER BY cat),
" FROM combinations ",
"GROUP BY id ",
"ORDER BY id"
) as query
FROM categories
Шаг 2 - скопируйте результат вышеуказанного запроса, вставьте его обратно в веб-интерфейс и запустите запрос
Думаю, у вас есть идея. Yo может реализовать его, как описано выше чисто в SQL или вы можете сгенерировать окончательный запрос в любой клиент по вашему выбору
Я пытался этот подход генерации запроса (но в Python) проблема в том, что запрос может легко достичь предела 256KB размера запроса в BigQuery
во-первых, давайте посмотрим, как «легко» это достичь предела 256KB
Если у вас есть 10 символов, как средняя длина категории - в этом случае вы можете покрыть с этим подходом - около 4750 категорий.
С 20 в среднем - охват составляет около 3480 и 30 - 2750
Если вы «сжать» SQL немного, удаляя пробелы и AS, и т.д. Вы можете сделать это, соответственно: 5400, 3800, 2970 для соответственно 10, 20, 30 символов
Так что, я бы сказал - да/Согласитесь - это, скорее всего, предел досягаемости до того 5K в реальном случае
Итак, во-вторых, давайте посмотрим, если это на самом деле большая проблема !
Как пример, предположим, что вам нужны категории 6K.Посмотрим, как вы можете разделить это на две партии (при условии, что сценарий 3K действительно работает в соответствии с первоначальным решением).
Нам нужно разделить категории на две группы - только на основе названий категорий
Итак, первая группа будет - МЕЖДУ «cat1» и «cat3000»
и вторая группа будет - между «cat3001» и «cat6000»
Итак, теперь работают обе группы с Step1 и Step2 с TEMP1 и temp2 таблиц как назначения
На шаге 1 - добавить (в самом низу запроса - после FROM categories
WHERE cat BETWEEN ‘cat1’ AND ‘cat3000’
для первой партии, и
WHERE cat BETWEEN ‘cat3001’ AND ‘cat6000’
для второй партии
Теперь перейдите к шагу 3
Шаг 3 - Объединение частичных результатов
#standardSQL
SELECT * EXCEPT(id2)
FROM temp1 FULL JOIN (
SELECT id AS id2, * EXCEPT(id) FROM temp2
) ON id = id2
-- ORDER BY id
Вы можете проверить последнюю логику с менее простыми/фиктивными данными
WITH temp1 AS (
SELECT 1 AS id, 1 AS is_A, 0 AS is_B UNION ALL
SELECT 2 AS id, 0 AS is_A, 1 AS is_B UNION ALL
SELECT 3 AS id, 1 AS is_A, 0 AS is_B
),
temp2 AS (
SELECT 1 AS id, 1 AS is_C, 0 AS is_D UNION ALL
SELECT 2 AS id, 1 AS is_C, 0 AS is_D UNION ALL
SELECT 3 AS id, 0 AS is_C, 1 AS is_D
)
Выше может быть легко расширен до более чем только две партий
Надеется, что это помогло
вы пробовали? –