Я задавал предыдущий вопрос о выполнении многоуровневого агрегирующего запроса по оси X здесь: Получите коды лучших патентных стран в общедоступном наборе данных BQ.
Вот как работает запрос (скопированный из принятого ответа):
Первые 2 страны по количеству и в этих странах 2 лучших кода по количеству
WITH A AS (
SELECT country_code
FROM `patents-public-data.patents.publications`
GROUP BY country_code
ORDER BY COUNT(1) DESC
LIMIT 2
), B AS (
SELECT
country_code,
application_kind,
COUNT(1) application_kind_count
FROM `patents-public-data.patents.publications`
WHERE country_code IN (SELECT country_code FROM A)
GROUP BY country_code, application_kind
), C AS (
SELECT
country_code,
application_kind,
application_kind_count,
DENSE_RANK() OVER(PARTITION BY country_code ORDER BY application_kind_count DESC) AS application_kind_rank
FROM B
)
SELECT
country_code,
application_kind,
application_kind_count
FROM C
WHERE application_kind_rank <= 2
И я получаю что-то вроде:
country_code application_kind count
JP A 125
JP U 124
CN A 118
CN U 101
Теперь я хотел бы добавить следующий поворот по оси Y: чтобы получить следующее:
Тогда окончательные результаты будут выглядеть так:
Я могу построить Y-запрос во втором запросе --
WITH A AS (
SELECT family_id
FROM `patents-public-data.patents.publications`
GROUP BY family_id
ORDER BY COUNT(1) DESC
LIMIT 2
), B AS (
SELECT
family_id,
priority_date,
COUNT(1) priority_date_count
FROM `patents-public-data.patents.publications`
WHERE family_id IN (SELECT family_id FROM A)
GROUP BY family_id, priority_date
), C AS (
SELECT
family_id,
priority_date,
priority_date_count,
DENSE_RANK() OVER(PARTITION BY family_id ORDER BY priority_date_count DESC) AS priority_date_rank
FROM B
)
SELECT
family_id,
priority_date,
priority_date_count
FROM C
WHERE priority_date_rank <= 2
Однако я не совсем уверен, как объединить их вместе, в одном запросе или в двух.
@MikhailBerlyant да, это правильно, не зная заранее опорных значений (т. Е. Вам нужно выполнить запрос агрегации, чтобы получить значения «ТОП»)
Ниже приведен стандартный SQL BigQuery, это просто демонстрация подхода, не претендующая на 100% представление запрошенной логики.
WITH A_X AS (
SELECT country_code FROM `patents-public-data.patents.publications`
GROUP BY country_code ORDER BY COUNT(1) DESC LIMIT 2
), B_X AS (
SELECT country_code, application_kind, COUNT(1) application_kind_count
FROM `patents-public-data.patents.publications` WHERE country_code IN (SELECT country_code FROM A_X)
GROUP BY country_code, application_kind
), C_X AS (
SELECT country_code, application_kind, application_kind_count,
DENSE_RANK() OVER(PARTITION BY country_code ORDER BY application_kind_count DESC) AS application_kind_rank
FROM B_X
), X AS (
SELECT country_code, application_kind, application_kind_count
FROM C_X WHERE application_kind_rank <= 2
), A_Y AS (
SELECT family_id FROM `patents-public-data.patents.publications`
JOIN X USING(country_code, application_kind)
GROUP BY family_id
ORDER BY COUNT(1) DESC LIMIT 2
), B_Y AS (
SELECT family_id, priority_date, COUNT(1) priority_date_count
FROM `patents-public-data.patents.publications` WHERE family_id IN (SELECT family_id FROM A_Y)
GROUP BY family_id, priority_date
), C_Y AS (
SELECT family_id, priority_date, priority_date_count,
DENSE_RANK() OVER(PARTITION BY family_id ORDER BY priority_date_count DESC) AS pos_date
FROM B_Y
), Y AS (
SELECT family_id, priority_date, pos_date, DENSE_RANK() OVER(ORDER BY family_id) pos_family
FROM C_Y WHERE pos_date <= 2
)
SELECT country_code, application_kind,
COUNTIF(pos_family = 1 AND pos_date = 1) `family1_date1`,
COUNTIF(pos_family = 1 AND pos_date = 2) `family1_date2`,
COUNTIF(pos_family = 2 AND pos_date = 1) `family2_date1`,
COUNTIF(pos_family = 2 AND pos_date = 2) `family2_date2`
FROM `patents-public-data.patents.publications`
JOIN Y USING(family_id, priority_date)
WHERE country_code IN (SELECT country_code FROM X)
AND application_kind IN (SELECT application_kind FROM x)
GROUP BY country_code, application_kind
результат
Очевидно, что сверху есть несколько нулей из-за логики пересечения
выглядит неплохо. Однако одно изменение, вместо того, чтобы говорить «family1_date1», можем ли мы сделать это фактическим значением «family1» и значением «date1»? Я могу пойти дальше и присудить награду позже. Хорошо сделано!
Это возможно только с динамическим SQL, где на первом этапе вы генерируете весь запрос с необходимыми псевдонимами на выходе, а затем на втором этапе вы фактически выполняете такой сгенерированный запрос. Здесь, на SO, есть много примеров такого подхода. Вы можете проверить мои недавние ответы - я помню, что у меня был аналогичный ответ день или несколько дней назад
Понятно, может быть, просто опубликовать ссылку на этот ответ и очень кратко показать, как будет отличаться запрос, если нам нужно будет получить имена динамических столбцов, и тогда я приму ответ?
@ David542 - это один из последних отвечать - там есть ссылка на еще один предыдущий ответ
так что это будет своего рода пересечение X и Y - верно? если так - должен быть простой случай