如何计算bigquery数组字段中元素的频率

Sye*_*que 5 google-bigquery bigquery-standard-sql

我有一张看起来像这样的表:

在此处输入图片说明

我正在寻找一个表格,它给出了字段中元素的频率计数l_0, l_1, l_2, l_3

例如,输出应如下所示:

| author_id  | year | l_o.name         | l_0.count| l1.name    | l1.count | l2.name             | l2.count| l3.name            | l3.count|
| 2164089123 | 1987 | biology          | 3        | botany     | 3        |                     |         |                    |         |
| 2595831531 | 1987 | computer science | 2        | simulation | 2        | computer simulation | 2       | mathematical model | 2       |
Run Code Online (Sandbox Code Playgroud)

编辑:

在某些情况下,数组字段可能有不止一种类型的元素。例如l_0可能是 ['biology', 'biology', 'geometry', 'geometry']. 在这种情况下,输出为字段l_0, l_1, l_2, l_3将与所有的元素嵌套的重复场l_0.name,并在所有相应的计数l_0.count

Ell*_*ard 8

这应该有效,假设您想以每个数组为基础:

SELECT
  author_id,
  year,
  (SELECT AS STRUCT ANY_VALUE(l_0) AS name, COUNT(*) AS count
   FROM UNNEST(l_0) AS l_0) AS l_0,
  (SELECT AS STRUCT ANY_VALUE(l_1) AS name, COUNT(*) AS count
   FROM UNNEST(l_1) AS l_1) AS l_1,
  (SELECT AS STRUCT ANY_VALUE(l_2) AS name, COUNT(*) AS count
   FROM UNNEST(l_2) AS l_2) AS l_2,
  (SELECT AS STRUCT ANY_VALUE(l_3) AS name, COUNT(*) AS count
   FROM UNNEST(l_3) AS l_3) AS l_3
FROM YourTable;
Run Code Online (Sandbox Code Playgroud)

为了避免如此多的重复,您可以使用 SQL UDF:

CREATE TEMP FUNCTION GetNameAndCount(elements ARRAY<STRING>) AS (
  (SELECT AS STRUCT ANY_VALUE(elem) AS name, COUNT(*) AS count
   FROM UNNEST(elements) AS elem)
);

SELECT
  author_id,
  year,
  GetNameAndCount(l_0) AS l_0,
  GetNameAndCount(l_1) AS l_1,
  GetNameAndCount(l_2) AS l_2,
  GetNameAndCount(l_3) AS l_3
FROM YourTable;
Run Code Online (Sandbox Code Playgroud)

如果您可能需要考虑数组中的多个不同名称,您可以让 UDF 返回一个包含相关计数的数组:

CREATE TEMP FUNCTION GetNamesAndCounts(elements ARRAY<STRING>) AS (
  ARRAY(
    SELECT AS STRUCT elem AS name, COUNT(*) AS count
    FROM UNNEST(elements) AS elem
    GROUP BY elem
    ORDER BY count
  )
);

SELECT
  author_id,
  year,
  GetNamesAndCounts(l_0) AS l_0,
  GetNamesAndCounts(l_1) AS l_1,
  GetNamesAndCounts(l_2) AS l_2,
  GetNamesAndCounts(l_3) AS l_3
FROM YourTable;
Run Code Online (Sandbox Code Playgroud)

请注意,如果您想跨行执行计数,则需要取消嵌套数组并GROUP BY在外部级别执行,但根据问题,这似乎不是您的意图。