首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BigQuery SQL -一种将多行多列的值传递给用户定义函数的方法

BigQuery SQL -一种将多行多列的值传递给用户定义函数的方法
EN

Stack Overflow用户
提问于 2016-11-10 19:19:40
回答 2查看 625关注 0票数 0

我想在BigQuery标准SQL中创建一个用户定义函数(CREATE TEMPORARY FUNCTION),它将接受从一堆行中聚合的值。

我的模式和表类似于:

代码语言:javascript
复制
| c1    | c2    | c3    | c4    |
|=======|=======|=======|=======|
| 1     | 1-1   | 3A    | 4A    |
| 1     | 1-1   | 3B    | 4B    |
| 1     | 1-1   | 3C    | 4C    |
| 1     | 1-2   | 3D    | 4D    |
| 2     | 2-1   | 3E    | 4E    |
| 2     | 2-1   | 3F    | 4F    |
| 2     | 2-2   | 3G    | 4G    |
| 2     | 2-2   | 3H    | 4H    |

我不能将原始模式更改为由嵌套或数组字段组成。

我希望按c1c2分组,并将c3c4的值传递给函数,同时能够在每一行的c3c4值之间进行匹配。一种方法是使用ARRAY_AGG并将值作为Array传递,但ARRAY_AGG是不确定的,因此来自c3c4的值可能具有与源表不同的顺序。Example

代码语言:javascript
复制
CREATE TEMPORARY FUNCTION
    tempConcatStrFunction(c3 ARRAY<STRING>, c4 ARRAY<STRING>)
    RETURNS STRING
    LANGUAGE js AS """
       return
        c3
        .map((item, index) => [ item, c4[index] ].join(','))
        .join(',');
    """;
WITH T as (
    SELECT c1, c2, ARRAY_AGG(c3) as c3, ARRAY_AGG(c4) as c4
    GROUP BY c1, c2
)
SELECT c1, c2, tempConcatStrFunction(c3, c4) as str from T

结果应该是:

代码语言:javascript
复制
| c1    | c2    | str                  |
|=======|=======|======================|
| 1     | 1-1   | 3A,4A,3B,4B,3C,4C    |
| 1     | 1-2   | 3D,4D                |
| 2     | 2-1   | 3E,4E,3F,4F          |
| 2     | 2-2   | 3G,4G,3H,4H          |

有什么想法可以达到这样的效果吗?

EN

回答 2

Stack Overflow用户

发布于 2016-11-11 00:59:29

有什么想法可以达到这样的效果吗?

我知道你的问题是关于如何使c3和c4在最后的字符串中相互匹配。不如让它像下面这样保持超级简单

代码语言:javascript
复制
SELECT c1, c2, STRING_AGG(CONCAT(c3, ',', c4)) AS str
FROM yourTable
GROUP BY c1, c2
票数 0
EN

Stack Overflow用户

发布于 2016-11-11 03:16:46

下面是几个可能有助于设置查询的示例:

代码语言:javascript
复制
WITH T AS (
  SELECT 1 AS c1, '1-1' AS c2, '3A' AS c3, '4A' AS c4 UNION ALL
  SELECT 1, '1-1', '3B', '4B' UNION ALL
  SELECT 1, '1-1', '3C', '4C' UNION ALL
  SELECT 1, '1-2', '3D', '4D' UNION ALL
  SELECT 2, '2-1', '3E', '4E' UNION ALL
  SELECT 2, '2-1', '3F', '4F' UNION ALL
  SELECT 2, '2-2', '3G', '4G' UNION ALL
  SELECT 2, '2-2', '3H', '4H'
)
SELECT
  c1,
  c2,
  STRING_AGG(CONCAT(c3, ',', c4)) AS str
FROM T
GROUP BY 1, 2;

它接受未聚合的输入(就像Mikhail的答案一样),并进行字符串连接。

如果输入已经聚合到数组中,理想情况下它们应该一起重复,例如:

代码语言:javascript
复制
WITH T AS (
  SELECT 1 AS c1, '1-1' AS c2, '3A' AS c3, '4A' AS c4 UNION ALL
  SELECT 1, '1-1', '3B', '4B' UNION ALL
  SELECT 1, '1-1', '3C', '4C' UNION ALL
  SELECT 1, '1-2', '3D', '4D' UNION ALL
  SELECT 2, '2-1', '3E', '4E' UNION ALL
  SELECT 2, '2-1', '3F', '4F' UNION ALL
  SELECT 2, '2-2', '3G', '4G' UNION ALL
  SELECT 2, '2-2', '3H', '4H'
),
U AS (
  SELECT
    c1,
    c2,
    ARRAY_AGG(STRUCT(c3, c4)) AS arr
  FROM T
)
SELECT
  c1,
  c2,
  (SELECT STRING_AGG(CONCAT(c3, ',', c4)) FROM UNNEST(arr)) AS str
FROM U
GROUP BY 1, 2;

如果数组是分开的,但顺序(和长度)是一致的,那么您可以在事后重新组合它们:

代码语言:javascript
复制
WITH T AS (
  SELECT 1 AS c1, '1-1' AS c2, '3A' AS c3, '4A' AS c4 UNION ALL
  SELECT 1, '1-1', '3B', '4B' UNION ALL
  SELECT 1, '1-1', '3C', '4C' UNION ALL
  SELECT 1, '1-2', '3D', '4D' UNION ALL
  SELECT 2, '2-1', '3E', '4E' UNION ALL
  SELECT 2, '2-1', '3F', '4F' UNION ALL
  SELECT 2, '2-2', '3G', '4G' UNION ALL
  SELECT 2, '2-2', '3H', '4H'
),
U AS (
  SELECT
    c1,
    c2,
    ARRAY_AGG(c3 ORDER BY c3, c4) AS arr3,
    ARRAY_AGG(c4 ORDER BY c3, c4) AS arr4
  FROM T
  GROUP BY 1, 2 
)
SELECT
  c1,
  c2,
  (SELECT STRING_AGG(CONCAT(arr4[OFFSET(off)], ',', c3))
   FROM UNNEST(arr3) AS c3 WITH OFFSET off) AS str
FROM U;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40526329

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档